Merge "Add sysui module for logging SystemUI atoms."
diff --git a/Android.bp b/Android.bp
index 0e3d374..b30bdaa 100644
--- a/Android.bp
+++ b/Android.bp
@@ -53,6 +53,7 @@
         "core/java/android/view/DisplayAdjustments.java",
     ],
     path: "core/java",
+    visibility: ["//frameworks/base/test-mock"],
 }
 
 filegroup {
@@ -73,6 +74,14 @@
 }
 
 filegroup {
+    name: "framework-identity-sources",
+    srcs: [
+        "identity/java/**/*.java",
+    ],
+    path: "identity/java",
+}
+
+filegroup {
     name: "framework-keystore-sources",
     srcs: [
         "keystore/java/**/*.java",
@@ -209,6 +218,7 @@
         ":framework-graphics-sources",
         ":framework-jobscheduler-sources", // jobscheduler is not a module for R
         ":framework-keystore-sources",
+        ":framework-identity-sources",
         ":framework-location-sources",
         ":framework-lowpan-sources",
         ":framework-mca-effect-sources",
@@ -231,6 +241,7 @@
         ":platform-compat-native-aidl",
 
         // AIDL sources from external directories
+        ":credstore_aidl",
         ":dumpstate_aidl",
         ":framework_native_aidl",
         ":gatekeeper_aidl",
@@ -294,6 +305,7 @@
             "core/java",
             "drm/java",
             "graphics/java",
+            "identity/java",
             "keystore/java",
             "location/java",
             "lowpan/java",
@@ -306,7 +318,6 @@
             "rs/java",
             "sax/java",
             "telecomm/java",
-            "wifi/java",
         ],
     },
 
@@ -327,8 +338,9 @@
         "framework-protos",
         "game-driver-protos",
         "android.hidl.base-V1.0-java",
-        "android.hardware.cas-V1.1-java",
         "android.hardware.cas-V1.0-java",
+        "android.hardware.cas-V1.1-java",
+        "android.hardware.cas-V1.2-java",
         "android.hardware.contexthub-V1.0-java",
         "android.hardware.gnss-V1.0-java",
         "android.hardware.health-V1.0-java-constants",
@@ -473,7 +485,6 @@
         "//frameworks/base/apex/permission/framework",
         "//frameworks/base/apex/statsd/service",
         "//frameworks/base/telephony",
-        "//frameworks/base/wifi",
         "//frameworks/opt/net/wifi/service",
     ],
 }
@@ -500,8 +511,7 @@
         "framework-sdkextensions-stubs-systemapi",
         // TODO(b/146167933): Use framework-statsd-stubs instead.
         "framework-statsd",
-        // TODO(b/140299412): should be framework-wifi-stubs
-        "framework-wifi",
+        "framework-wifi-stubs",
         "ike-stubs",
         // TODO(b/147200698): should be the stub of framework-tethering
         "framework-tethering",
@@ -540,7 +550,8 @@
         "compat-changeid-annotation-processor",
     ],
     static_libs: [
-        "exoplayer2-core"
+        "exoplayer2-core",
+        "android.hardware.wifi-V1.0-java-constants",
     ]
 }
 
@@ -586,7 +597,7 @@
 genrule {
     name: "framework-statslog-gen",
     tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out)",
+    cmd: "$(location stats-log-api-gen) --java $(out) --worksource",
     out: ["android/util/StatsLogInternal.java"],
 }
 
@@ -1126,9 +1137,10 @@
 }
 
 // Avoid including Parcelable classes as we don't want to have two copies of
-// Parcelable cross the process.
+// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
+// and TeleService app (packages/services/Telephony).
 filegroup {
-    name: "framework-telephony-stack-shared-srcs",
+    name: "framework-telephony-common-shared-srcs",
     srcs: [
         "core/java/android/os/BasicShellCommandHandler.java",
         "core/java/android/os/RegistrantList.java",
@@ -1151,6 +1163,21 @@
 }
 
 // Avoid including Parcelable classes as we don't want to have two copies of
+// Parcelable cross the process. This is used by framework-telephony (frameworks/base/telephony).
+filegroup {
+    name: "framework-telephony-shared-srcs",
+    srcs: [
+        "core/java/android/util/RecurrenceRule.java",
+        "core/java/com/android/internal/os/SomeArgs.java",
+        "core/java/com/android/internal/util/BitwiseInputStream.java",
+        "core/java/com/android/internal/util/BitwiseOutputStream.java",
+        "core/java/com/android/internal/util/HexDump.java",
+        "core/java/com/android/internal/util/IndentingPrintWriter.java",
+        "core/java/com/android/internal/util/Preconditions.java",
+    ],
+}
+
+// Avoid including Parcelable classes as we don't want to have two copies of
 // Parcelable cross the process.
 filegroup {
     name: "framework-cellbroadcast-shared-srcs",
@@ -1189,7 +1216,7 @@
         "core/java/com/android/internal/util/Protocol.java",
         "core/java/com/android/internal/util/Preconditions.java",
         "telephony/java/android/telephony/Annotation.java",
-	":net-utils-framework-wifi-common-srcs",
+        ":net-utils-framework-wifi-common-srcs",
     ],
     libs: [
         "framework-annotations-lib",
@@ -1216,6 +1243,7 @@
         "core/java/com/android/internal/util/StateMachine.java",
         "core/java/com/android/internal/util/WakeupMessage.java",
     ],
+    visibility: ["//frameworks/opt/net/wifi/service"],
 }
 
 // TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
@@ -1266,13 +1294,15 @@
     aidl: {
         export_include_dirs: ["telephony/java"],
     },
-    sdk_version: "system_current",
+    sdk_version: "core_current",
+    libs: ["android_system_stubs_current"],
 }
 
 java_library {
     name: "framework-telephony",
     srcs: [
         ":framework-telephony-sources",
+        ":framework-telephony-shared-srcs",
     ],
     // TODO: change to framework-system-stub to build against system APIs.
     libs: [
@@ -1291,7 +1321,7 @@
             "frameworks/native/aidl/gui",
         ]
     },
-    jarjar_rules: ":telephony-framework-jarjar-rules",
+    jarjar_rules: ":framework-telephony-jarjar-rules",
     dxflags: [
         "--core-library",
         "--multi-dex",
@@ -1310,6 +1340,6 @@
 }
 
 filegroup {
-    name: "telephony-framework-jarjar-rules",
+    name: "framework-telephony-jarjar-rules",
     srcs: ["telephony/framework-telephony-jarjar-rules.txt"],
 }
diff --git a/StubLibraries.bp b/StubLibraries.bp
index cdc0d32..6927f44 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -181,7 +181,7 @@
 // They however are NOT used for building the API stub.
 droidstubs {
     name: "module-app-api",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: ["metalava-api-stubs-default"],
     libs: ["framework-all"],
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args +
@@ -211,7 +211,7 @@
 
 droidstubs {
     name: "module-lib-api",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: ["metalava-api-stubs-default"],
     libs: ["framework-all"],
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args +
@@ -245,7 +245,7 @@
 // the ones with 'client=MODULE_LIBRARIES'.
 droidstubs {
     name: "module-app-api-stubs-docs",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: ["metalava-api-stubs-default"],
     libs: ["framework-all"],
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args +
@@ -259,7 +259,7 @@
 
 droidstubs {
     name: "module-lib-api-stubs-docs",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    defaults: ["metalava-api-stubs-default"],
     libs: ["framework-all"],
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args +
diff --git a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
index f32bf9a..c62aad6 100644
--- a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
@@ -20,6 +20,7 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.perftests.utils.BenchmarkState;
@@ -149,7 +150,7 @@
                         mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame,
                         mOutContentInsets, mOutVisibleInsets, mOutStableInsets,
                         mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration,
-                        mOutSurfaceControl, mOutInsetsState);
+                        mOutSurfaceControl, mOutInsetsState, new Point());
             }
         }
     }
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp
index 2e88115..24309d7 100644
--- a/apex/appsearch/framework/Android.bp
+++ b/apex/appsearch/framework/Android.bp
@@ -30,14 +30,13 @@
     libs: [
         "framework-minus-apex",  // TODO(b/146218515) should be framework-system-stubs
     ],
-    static_libs: [
-        "icing-java-proto-lite",
-    ],
+    static_libs: ["icing-java-proto-lite"],
     visibility: [
-        "//frameworks/base/apex/appsearch:__subpackages__",
         // TODO(b/146218515) remove this when framework is built with the stub of appsearch
         "//frameworks/base",
+        "//frameworks/base/apex/appsearch:__subpackages__",
     ],
+    permitted_packages: ["android.app.appsearch"],
     apex_available: ["com.android.appsearch"],
 }
 
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearch.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearch.java
index e779b69..fd20186 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearch.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearch.java
@@ -16,10 +16,11 @@
 
 package android.app.appsearch;
 
-import android.annotation.CurrentTimeSecondsLong;
+import android.annotation.CurrentTimeMillisLong;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.appsearch.AppSearchSchema.PropertyConfig;
 import android.os.Bundle;
 import android.util.Log;
 
@@ -32,7 +33,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Objects;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Collection of all AppSearch Document Types.
@@ -150,14 +150,14 @@
         }
 
         /**
-         * Get the creation timestamp in seconds of the {@link Document}.
+         * Get the creation timestamp in milliseconds of the {@link Document}. Value will be in the
+         * {@link System#currentTimeMillis()} time base.
          *
          * @hide
          */
-        // TODO(b/143789408) Change seconds to millis with Icing library.
-        @CurrentTimeSecondsLong
-        public long getCreationTimestampSecs() {
-            return mProto.getCreationTimestampSecs();
+        @CurrentTimeMillisLong
+        public long getCreationTimestampMillis() {
+            return mProto.getCreationTimestampMs();
         }
 
         /**
@@ -381,8 +381,7 @@
                 mBuilderTypeInstance = (BuilderType) this;
                 mProtoBuilder.setUri(uri).setSchema(schemaType);
                  // Set current timestamp for creation timestamp by default.
-                setCreationTimestampSecs(
-                        TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
+                setCreationTimestampMillis(System.currentTimeMillis());
             }
 
             /**
@@ -404,14 +403,15 @@
             }
 
             /**
-             * Set the creation timestamp in seconds of the {@link Document}.
+             * Set the creation timestamp in milliseconds of the {@link Document}. Should be set
+             * using a value obtained from the {@link System#currentTimeMillis()} time base.
              *
              * @hide
              */
             @NonNull
-            public BuilderType setCreationTimestampSecs(
-                    @CurrentTimeSecondsLong long creationTimestampSecs) {
-                mProtoBuilder.setCreationTimestampSecs(creationTimestampSecs);
+            public BuilderType setCreationTimestampMillis(
+                    @CurrentTimeMillisLong long creationTimestampMillis) {
+                mProtoBuilder.setCreationTimestampMs(creationTimestampMillis);
                 return mBuilderTypeInstance;
             }
 
@@ -575,10 +575,6 @@
      * @hide
      */
     public static class Email extends Document {
-
-        /** The name of the schema type for {@link Email} documents.*/
-        public static final String SCHEMA_TYPE = "builtin:Email";
-
         private static final String KEY_FROM = "from";
         private static final String KEY_TO = "to";
         private static final String KEY_CC = "cc";
@@ -586,14 +582,53 @@
         private static final String KEY_SUBJECT = "subject";
         private static final String KEY_BODY = "body";
 
-        /**
-         * Creates a new {@link Email} from the contents of an existing {@link Document}.
-         *
-         * @param document The {@link Document} containing the email content.
-         */
-        public Email(@NonNull Document document) {
-            super(document);
-        }
+        /** The name of the schema type for {@link Email} documents.*/
+        public static final String SCHEMA_TYPE = "builtin:Email";
+
+        public static final AppSearchSchema SCHEMA = AppSearchSchema.newBuilder(SCHEMA_TYPE)
+                .addProperty(AppSearchSchema.newPropertyBuilder(KEY_FROM)
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build()
+
+                ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_TO)
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build()
+
+                ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_CC)
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build()
+
+                ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BCC)
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build()
+
+                ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_SUBJECT)
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build()
+
+                ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BODY)
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build()
+
+                ).build();
 
         /**
          * Creates a new {@link Email.Builder}.
@@ -605,6 +640,15 @@
         }
 
         /**
+         * Creates a new {@link Email} from the contents of an existing {@link Document}.
+         *
+         * @param document The {@link Document} containing the email content.
+         */
+        public Email(@NonNull Document document) {
+            super(document);
+        }
+
+        /**
          * Get the from address of {@link Email}.
          *
          * @return Returns the subject of {@link Email} or {@code null} if it's not been set yet.
@@ -616,10 +660,10 @@
         }
 
         /**
-         * Get the destination address of {@link Email}.
+         * Get the destination addresses of {@link Email}.
          *
-         * @return Returns the destination address of {@link Email} or {@code null} if it's not been
-         *         set yet.
+         * @return Returns the destination addresses of {@link Email} or {@code null} if it's not
+         *         been set yet.
          * @hide
          */
         @Nullable
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
new file mode 100644
index 0000000..773db93
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appsearch;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Provides access to multiple results from a batch operation accepting multiple inputs.
+ *
+ * @param <KeyType> The type of the keys for {@link #getResults} and {@link #getFailures}.
+ * @param <ValueType> The type of result objects associated with the keys.
+ * @hide
+ */
+public class AppSearchBatchResult<KeyType, ValueType> implements Parcelable {
+    @NonNull private final Map<KeyType, ValueType> mResults;
+    @NonNull private final Map<KeyType, Throwable> mFailures;
+
+    private AppSearchBatchResult(
+            @NonNull Map<KeyType, ValueType> results, @NonNull Map<KeyType, Throwable> failures) {
+        mResults = results;
+        mFailures = failures;
+    }
+
+    private AppSearchBatchResult(@NonNull Parcel in) {
+        mResults = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null));
+        mFailures = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null));
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeMap(mResults);
+        dest.writeMap(mFailures);
+    }
+
+    /** Returns {@code true} if this {@link AppSearchBatchResult} has no failures. */
+    public boolean isSuccess() {
+        return mFailures.isEmpty();
+    }
+
+    /**
+     * Returns a {@link Map} of all successful keys mapped to the results they produced.
+     *
+     * <p>The values of the {@link Map} may be {@code null}.
+     */
+    @NonNull
+    public Map<KeyType, ValueType> getResults() {
+        return mResults;
+    }
+
+    /**
+     * Returns a {@link Map} of all failed keys mapped to a {@link Throwable} representing the cause
+     * of failure.
+     *
+     * <p>The values of the {@link Map} may be {@code null}.
+     */
+    @NonNull
+    public Map<KeyType, Throwable> getFailures() {
+        return mFailures;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<AppSearchBatchResult> CREATOR =
+            new Creator<AppSearchBatchResult>() {
+        @NonNull
+        @Override
+        public AppSearchBatchResult createFromParcel(@NonNull Parcel in) {
+            return new AppSearchBatchResult(in);
+        }
+
+        @NonNull
+        @Override
+        public AppSearchBatchResult[] newArray(int size) {
+            return new AppSearchBatchResult[size];
+        }
+    };
+
+    /**
+     * Creates a new {@link Builder} for this {@link AppSearchBatchResult}.
+     * @hide
+     */
+    @NonNull
+    public static <KeyType, ValueType> Builder<KeyType, ValueType> newBuilder() {
+        return new Builder<>();
+    }
+
+    /**
+     * Builder for {@link AppSearchBatchResult} objects.
+     *
+     * @param <KeyType> The type of keys.
+     * @param <ValueType> The type of result objects associated with the keys.
+     * @hide
+     */
+    public static final class Builder<KeyType, ValueType> {
+        @NonNull private final Map<KeyType, ValueType> mResults = new ArrayMap<>();
+        @NonNull private final Map<KeyType, Throwable> mFailures = new ArrayMap<>();
+
+        private Builder() {}
+
+        /**
+         * Registers that the {@code key} was processed successfully and associates it with
+         * {@code value}. Any previous mapping for a key, whether success or failure, is deleted.
+         */
+        public Builder setSuccess(@NonNull KeyType key, @Nullable ValueType value) {
+            mResults.put(key, value);
+            mFailures.remove(key);
+            return this;
+        }
+
+        /**
+         * Registers that the {@code key} failed and associates it with {@code throwable}. Any
+         * previous mapping for a key, whether success or failure, is deleted.
+         */
+        public Builder setFailure(@NonNull KeyType key, @Nullable Throwable throwable) {
+            mFailures.put(key, throwable);
+            mResults.remove(key);
+            return this;
+        }
+
+        /** Builds an {@link AppSearchBatchResult} from the contents of this {@link Builder}. */
+        @NonNull
+        public AppSearchBatchResult<KeyType, ValueType> build() {
+            return new AppSearchBatchResult<>(mResults, mFailures);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index 0aa685d..e3f6b3d 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -26,12 +26,15 @@
 
 import com.google.android.icing.proto.SchemaProto;
 import com.google.android.icing.proto.SearchResultProto;
+import com.google.android.icing.proto.StatusProto;
 import com.google.android.icing.protobuf.InvalidProtocolBufferException;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
 
 /**
  * This class provides access to the centralized AppSearch index maintained by the system.
@@ -51,84 +54,129 @@
     }
 
     /**
-     * Sets the schema being used by documents provided to the #put method.
+     * Sets the schema being used by documents provided to the {@link #putDocuments} method.
      *
-     * <p>This operation is performed asynchronously. On success, the provided callback will be
-     * called with {@code null}. On failure, the provided callback will be called with a
-     * {@link Throwable} describing the failure.
+     * <p>The schema provided here is compared to the stored copy of the schema previously supplied
+     * to {@link #setSchema}, if any, to determine how to treat existing documents. The following
+     * types of schema modifications are always safe and are made without deleting any existing
+     * documents:
+     * <ul>
+     *     <li>Addition of new types
+     *     <li>Addition of new
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
+     *             OPTIONAL} or
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
+     *             REPEATED} properties to a type
+     *     <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
+     *             OPTIONAL} property into a
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
+     *             REPEATED} property.
+     * </ul>
+     *
+     * <p>The following types of schema changes are not backwards-compatible. Supplying a schema
+     * with such changes will result in this call throwing an {@link IllegalSchemaException}
+     * describing the incompatibility, and the previously set schema will remain active:
+     * <ul>
+     *     <li>Removal of an existing type
+     *     <li>Removal of a property from a type
+     *     <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
+     *     <li>For properties of {@code Document} type, changing the schema type of
+     *         {@code Document Documents} of that property
+     *     <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL
+     *             OPTIONAL} property into a
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED
+     *             REQUIRED} property).
+     *     <li>Adding a
+     *         {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED
+     *             REQUIRED} property.
+     * </ul>
+     *
+     * <p>If you need to make non-backwards-compatible changes as described above, instead use the
+     * {@link #setSchema(List, boolean)} method with the {@code forceOverride} parameter set to
+     * {@code true}.
      *
      * <p>It is a no-op to set the same schema as has been previously set; this is handled
      * efficiently.
      *
-     * <p>AppSearch automatically handles the following types of schema changes:
-     * <ul>
-     *     <li>Addition of new types (No changes to storage or index)
-     *     <li>Removal of an existing type (All documents of the removed type are deleted)
-     *     <li>Addition of new 'optional' property to a type (No changes to storage or index)
-     *     <li>Removal of existing property of any cardinality (All documents reindexed)
-     * </ul>
-     *
-     * <p>This method will return an error when attempting to make the following types of changes:
-     * <ul>
-     *     <li>Changing the type of an existing property
-     *     <li>Adding a 'required' property
-     * </ul>
-     *
-     * @param schema The schema config for this app.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive errors resulting from setting the schema. If the
-     *                 operation succeeds, the callback will be invoked with {@code null}.
+     * @param schemas The schema configs for the types used by the calling app.
+     * @throws IllegalSchemaException If the provided schema is invalid, or is incompatible with the
+     *     previous schema.
      *
      * @hide
      */
-    // TODO(b/143789408): linkify #put after that API is created
-    // TODO(b/145635424): add a 'force' param to setSchema after the corresponding API is finalized
-    //     in Icing Library
-    // TODO(b/145635424): Update the documentation above once the Schema mutation APIs of Icing
-    //     Library are finalized
-    public void setSchema(
-            @NonNull AppSearchSchema schema,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<? super Throwable> callback) {
-        SchemaProto schemaProto = schema.getProto();
-        byte[] schemaBytes = schemaProto.toByteArray();
-        AndroidFuture<Void> future = new AndroidFuture<>();
-        try {
-            mService.setSchema(schemaBytes, future);
-        } catch (RemoteException e) {
-            future.completeExceptionally(e);
-        }
-        future.whenCompleteAsync((noop, err) -> callback.accept(err), executor);
+    public void setSchema(@NonNull AppSearchSchema... schemas) {
+        setSchema(Arrays.asList(schemas), /*forceOverride=*/false);
     }
 
     /**
-     * Index {@link Document} to AppSearch
+     * Sets the schema being used by documents provided to the {@link #putDocuments} method.
      *
-     * <p>You should not call this method directly; instead, use the {@code AppSearch#put()} API
-     * provided by JetPack.
+     * <p>This method is similar to {@link #setSchema(AppSearchSchema...)}, except for the
+     * {@code forceOverride} parameter. If a backwards-incompatible schema is specified but the
+     * {@code forceOverride} parameter is set to {@code true}, instead of throwing an
+     * {@link IllegalSchemaException}, all documents which are not compatible with the new schema
+     * will be deleted and the incompatible schema will be applied.
      *
-     * <p>The schema should be set via {@link #setSchema} method.
+     * @param schemas The schema configs for the types used by the calling app.
+     * @param forceOverride Whether to force the new schema to be applied even if there are
+     *     incompatible changes versus the previously set schema. Documents which are incompatible
+     *     with the new schema will be deleted.
+     * @throws IllegalSchemaException If the provided schema is invalid, or is incompatible with the
+     *     previous schema and the {@code forceOverride} parameter is set to {@code false}.
+     *
+     * @hide
+     */
+    public void setSchema(@NonNull List<AppSearchSchema> schemas, boolean forceOverride) {
+        // Prepare the merged schema for transmission.
+        SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
+        for (AppSearchSchema schema : schemas) {
+            schemaProtoBuilder.addTypes(schema.getProto());
+        }
+
+        // Serialize and send the schema.
+        // TODO: This should use com.android.internal.infra.RemoteStream or another mechanism to
+        //  avoid binder limits.
+        byte[] schemaBytes = schemaProtoBuilder.build().toByteArray();
+        AndroidFuture<Void> future = new AndroidFuture<>();
+        try {
+            mService.setSchema(schemaBytes, forceOverride, future);
+        } catch (RemoteException e) {
+            future.completeExceptionally(e);
+        }
+        getFutureOrThrow(future);
+    }
+
+    /**
+     * Index {@link android.app.appsearch.AppSearch.Document Documents} into AppSearch.
+     *
+     * <p>You should not call this method directly; instead, use the
+     * {@code AppSearch#putDocuments()} API provided by JetPack.
+     *
+     * <p>Each {@link AppSearch.Document Document's} {@code schemaType} field must be set to the
+     * name of a schema type previously registered via the {@link #setSchema} method.
      *
      * @param documents {@link Document Documents} that need to be indexed.
-     * @param executor Executor on which to invoke the callback.
-     * @param callback Callback to receive errors resulting from setting the schema. If the
-     *                 operation succeeds, the callback will be invoked with {@code null}.
+     * @return An {@link AppSearchBatchResult} mapping the document URIs to {@link Void} if they
+     *     were successfully indexed, or a {@link Throwable} describing the failure if they could
+     *     not be indexed.
+     * @hide
      */
-    public void put(@NonNull List<Document> documents,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<? super Throwable> callback) {
-        AndroidFuture<Void> future = new AndroidFuture<>();
+    public AppSearchBatchResult<String, Void> putDocuments(@NonNull List<Document> documents) {
+        // TODO(b/146386470): Transmit these documents as a RemoteStream instead of sending them in
+        // one big list.
+        List<byte[]> documentsBytes = new ArrayList<>(documents.size());
         for (Document document : documents) {
-            // TODO(b/146386470) batching Document protos
-            try {
-                mService.put(document.getProto().toByteArray(), future);
-            } catch (RemoteException e) {
-                future.completeExceptionally(e);
-                break;
-            }
+            documentsBytes.add(document.getProto().toByteArray());
         }
-        // TODO(b/147614371) Fix error report for multiple documents.
-        future.whenCompleteAsync((noop, err) -> callback.accept(err), executor);
+        AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
+        try {
+            mService.putDocuments(documentsBytes, future);
+        } catch (RemoteException e) {
+            future.completeExceptionally(e);
+        }
+        return getFutureOrThrow(future);
     }
 
     /**
@@ -197,11 +245,11 @@
                     callback.accept(null, e);
                     return;
                 }
-                if (searchResultProto.hasError()) {
+                if (searchResultProto.getStatus().getCode() != StatusProto.Code.OK) {
                     // TODO(sidchhabra): Add better exception handling.
                     callback.accept(
                             null,
-                            new RuntimeException(searchResultProto.getError().getErrorMessage()));
+                            new RuntimeException(searchResultProto.getStatus().getMessage()));
                     return;
                 }
                 SearchResults searchResults = new SearchResults(searchResultProto);
@@ -220,4 +268,21 @@
             future.completeExceptionally(e);
         }
     }
+
+    private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) {
+        try {
+            return future.get();
+        } catch (Throwable e) {
+            if (e instanceof ExecutionException) {
+                e = e.getCause();
+            }
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            }
+            if (e instanceof Error) {
+                throw (Error) e;
+            }
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
index 7e5f187..1d54dc4 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
@@ -18,41 +18,38 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.util.ArraySet;
 
 import com.android.internal.annotations.VisibleForTesting;
 
 import com.google.android.icing.proto.PropertyConfigProto;
-import com.google.android.icing.proto.SchemaProto;
 import com.google.android.icing.proto.SchemaTypeConfigProto;
+import com.google.android.icing.proto.TermMatchType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
 
 /**
- * Representation of the AppSearch Schema.
+ * The AppSearch Schema for a particular type of document.
  *
- * <p>The schema is the set of document types, properties, and config (like tokenization type)
- * understood by AppSearch for this app.
+ * <p>For example, an e-mail message or a music recording could be a schema type.
+ *
+ * <p>The schema consists of type information, properties, and config (like tokenization type).
  *
  * @hide
  */
 public final class AppSearchSchema {
-    private final SchemaProto mProto;
+    private final SchemaTypeConfigProto mProto;
 
-    private AppSearchSchema(SchemaProto proto) {
+    private AppSearchSchema(SchemaTypeConfigProto proto) {
         mProto = proto;
     }
 
     /** Creates a new {@link AppSearchSchema.Builder}. */
     @NonNull
-    public static AppSearchSchema.Builder newBuilder() {
-        return new AppSearchSchema.Builder();
-    }
-
-    /** Creates a new {@link SchemaType.Builder}. */
-    @NonNull
-    public static SchemaType.Builder newSchemaTypeBuilder(@NonNull String typeName) {
-        return new SchemaType.Builder(typeName);
+    public static AppSearchSchema.Builder newBuilder(@NonNull String typeName) {
+        return new AppSearchSchema.Builder(typeName);
     }
 
     /** Creates a new {@link PropertyConfig.Builder}. */
@@ -61,32 +58,34 @@
         return new PropertyConfig.Builder(propertyName);
     }
 
-    /** Creates a new {@link IndexingConfig.Builder}. */
-    @NonNull
-    public static IndexingConfig.Builder newIndexingConfigBuilder() {
-        return new IndexingConfig.Builder();
-    }
-
     /**
-     * Returns the schema proto populated by the {@link AppSearchSchema} builders.
+     * Returns the {@link SchemaTypeConfigProto} populated by this builder.
      * @hide
      */
     @NonNull
     @VisibleForTesting
-    public SchemaProto getProto() {
+    public SchemaTypeConfigProto getProto() {
         return mProto;
     }
 
+    @Override
+    public String toString() {
+        return mProto.toString();
+    }
+
     /** Builder for {@link AppSearchSchema objects}. */
     public static final class Builder {
-        private final SchemaProto.Builder mProtoBuilder = SchemaProto.newBuilder();
+        private final SchemaTypeConfigProto.Builder mProtoBuilder =
+                SchemaTypeConfigProto.newBuilder();
 
-        private Builder() {}
+        private Builder(@NonNull String typeName) {
+            mProtoBuilder.setSchemaType(typeName);
+        }
 
-        /** Adds a supported type to this app's AppSearch schema. */
+        /** Adds a property to the given type. */
         @NonNull
-        public AppSearchSchema.Builder addType(@NonNull SchemaType schemaType) {
-            mProtoBuilder.addTypes(schemaType.mProto);
+        public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
+            mProtoBuilder.addProperties(propertyConfig.mProto);
             return this;
         }
 
@@ -97,51 +96,19 @@
          */
         @NonNull
         public AppSearchSchema build() {
+            Set<String> propertyNames = new ArraySet<>();
+            for (PropertyConfigProto propertyConfigProto : mProtoBuilder.getPropertiesList()) {
+                if (!propertyNames.add(propertyConfigProto.getPropertyName())) {
+                    throw new IllegalSchemaException(
+                            "Property defined more than once: "
+                                    + propertyConfigProto.getPropertyName());
+                }
+            }
             return new AppSearchSchema(mProtoBuilder.build());
         }
     }
 
     /**
-     * Represents a type of a document.
-     *
-     * <p>For example, an e-mail message or a music recording could be a schema type.
-     */
-    public static final class SchemaType {
-        private final SchemaTypeConfigProto mProto;
-
-        private SchemaType(SchemaTypeConfigProto proto) {
-            mProto = proto;
-        }
-
-        /** Builder for {@link SchemaType} objects. */
-        public static final class Builder {
-            private final SchemaTypeConfigProto.Builder mProtoBuilder =
-                    SchemaTypeConfigProto.newBuilder();
-
-            private Builder(@NonNull String typeName) {
-                mProtoBuilder.setSchemaType(typeName);
-            }
-
-            /** Adds a property to the given type. */
-            @NonNull
-            public SchemaType.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
-                mProtoBuilder.addProperties(propertyConfig.mProto);
-                return this;
-            }
-
-            /**
-             * Constructs a new {@link SchemaType} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             */
-            @NonNull
-            public SchemaType build() {
-                return new SchemaType(mProtoBuilder.build());
-            }
-        }
-    }
-
-    /**
      * Configuration for a single property (field) of a document type.
      *
      * <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be
@@ -197,130 +164,14 @@
         /** Exactly one value [1]. */
         public static final int CARDINALITY_REQUIRED = 3;
 
-        private final PropertyConfigProto mProto;
-
-        private PropertyConfig(PropertyConfigProto proto) {
-            mProto = proto;
-        }
-
-        /**
-         * Builder for {@link PropertyConfig}.
-         *
-         * <p>The following properties must be set, or {@link PropertyConfig} construction will
-         * fail:
-         * <ul>
-         *     <li>dataType
-         *     <li>cardinality
-         * </ul>
-         *
-         * <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType}
-         * is also required.
-         */
-        public static final class Builder {
-            private final PropertyConfigProto.Builder mProtoBuilder =
-                    PropertyConfigProto.newBuilder();
-
-            private Builder(String propertyName) {
-                mProtoBuilder.setPropertyName(propertyName);
-            }
-
-            /**
-             * Type of data the property contains (e.g. string, int, bytes, etc).
-             *
-             * <p>This property must be set.
-             */
-            @NonNull
-            public PropertyConfig.Builder setDataType(@DataType int dataType) {
-                PropertyConfigProto.DataType.Code dataTypeProto =
-                        PropertyConfigProto.DataType.Code.forNumber(dataType);
-                if (dataTypeProto == null) {
-                    throw new IllegalArgumentException("Invalid dataType: " + dataType);
-                }
-                mProtoBuilder.setDataType(dataTypeProto);
-                return this;
-            }
-
-            /**
-             * The logical schema-type of the contents of this property.
-             *
-             * <p>Only required when {@link #setDataType(int)} is set to
-             * {@link #DATA_TYPE_DOCUMENT}. Otherwise, it is ignored.
-             */
-            @NonNull
-            public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
-                mProtoBuilder.setSchemaType(schemaType);
-                return this;
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>This property must be set.
-             */
-            @NonNull
-            public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                PropertyConfigProto.Cardinality.Code cardinalityProto =
-                        PropertyConfigProto.Cardinality.Code.forNumber(cardinality);
-                if (cardinalityProto == null) {
-                    throw new IllegalArgumentException("Invalid cardinality: " + cardinality);
-                }
-                mProtoBuilder.setCardinality(cardinalityProto);
-                return this;
-            }
-
-            /**
-             * Configures how this property should be indexed.
-             *
-             * <p>If this is not supplied, the property will not be indexed at all.
-             */
-            @NonNull
-            public PropertyConfig.Builder setIndexingConfig(
-                    @NonNull IndexingConfig indexingConfig) {
-                mProtoBuilder.setIndexingConfig(indexingConfig.mProto);
-                return this;
-            }
-
-            /**
-             * Constructs a new {@link PropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalSchemaException If the property is not correctly populated (e.g.
-             *     missing {@code dataType}).
-             */
-            @NonNull
-            public PropertyConfig build() {
-                if (mProtoBuilder.getDataType() == PropertyConfigProto.DataType.Code.UNKNOWN) {
-                    throw new IllegalSchemaException("Missing field: dataType");
-                }
-                if (mProtoBuilder.getSchemaType().isEmpty()
-                        && mProtoBuilder.getDataType()
-                                == PropertyConfigProto.DataType.Code.DOCUMENT) {
-                    throw new IllegalSchemaException(
-                            "Missing field: schemaType (required for configs with "
-                                    + "dataType = DOCUMENT)");
-                }
-                if (mProtoBuilder.getCardinality()
-                        == PropertyConfigProto.Cardinality.Code.UNKNOWN) {
-                    throw new IllegalSchemaException("Missing field: cardinality");
-                }
-                return new PropertyConfig(mProtoBuilder.build());
-            }
-        }
-    }
-
-    /** Configures how a property should be indexed so that it can be retrieved by queries. */
-    public static final class IndexingConfig {
         /** Encapsulates the configurations on how AppSearch should query/index these terms. */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.TermMatchType.Code.
-        @IntDef(prefix = {"TERM_MATCH_TYPE_"}, value = {
-                TERM_MATCH_TYPE_UNKNOWN,
-                TERM_MATCH_TYPE_EXACT_ONLY,
-                TERM_MATCH_TYPE_PREFIX,
+        @IntDef(prefix = {"INDEXING_TYPE_"}, value = {
+                INDEXING_TYPE_NONE,
+                INDEXING_TYPE_EXACT_TERMS,
+                INDEXING_TYPE_PREFIXES,
         })
         @Retention(RetentionPolicy.SOURCE)
-        public @interface TermMatchType {}
+        public @interface IndexingType {}
 
         /**
          * Content in this property will not be tokenized or indexed.
@@ -328,9 +179,9 @@
          * <p>Useful if the data type is not made up of terms (e.g.
          * {@link PropertyConfig#DATA_TYPE_DOCUMENT} or {@link PropertyConfig#DATA_TYPE_BYTES}
          * type). All the properties inside the nested property won't be indexed regardless of the
-         * value of {@code termMatchType} for the nested properties.
+         * value of {@code indexingType} for the nested properties.
          */
-        public static final int TERM_MATCH_TYPE_UNKNOWN = 0;
+        public static final int INDEXING_TYPE_NONE = 0;
 
         /**
          * Content in this property should only be returned for queries matching the exact tokens
@@ -338,7 +189,7 @@
          *
          * <p>Ex. A property with "fool" should NOT match a query for "foo".
          */
-        public static final int TERM_MATCH_TYPE_EXACT_ONLY = 1;
+        public static final int INDEXING_TYPE_EXACT_TERMS = 1;
 
         /**
          * Content in this property should be returned for queries that are either exact matches or
@@ -346,7 +197,7 @@
          *
          * <p>Ex. A property with "fool" <b>should</b> match a query for "foo".
          */
-        public static final int TERM_MATCH_TYPE_PREFIX = 2;
+        public static final int INDEXING_TYPE_PREFIXES = 2;
 
         /** Configures how tokens should be extracted from this property. */
         // NOTE: The integer values of these constants must match the proto enum constants in
@@ -367,59 +218,151 @@
         /** Tokenization for plain text. */
         public static final int TOKENIZER_TYPE_PLAIN = 1;
 
-        private final com.google.android.icing.proto.IndexingConfig mProto;
+        private final PropertyConfigProto mProto;
 
-        private IndexingConfig(com.google.android.icing.proto.IndexingConfig proto) {
+        private PropertyConfig(PropertyConfigProto proto) {
             mProto = proto;
         }
 
+        @Override
+        public String toString() {
+            return mProto.toString();
+        }
+
         /**
-         * Builder for {@link IndexingConfig} objects.
+         * Builder for {@link PropertyConfig}.
          *
-         * <p>You may skip adding an {@link IndexingConfig} for a property, which is equivalent to
-         * an {@link IndexingConfig} having {@code termMatchType} equal to
-         * {@link #TERM_MATCH_TYPE_UNKNOWN}. In this case the property will not be indexed.
+         * <p>The following properties must be set, or {@link PropertyConfig} construction will
+         * fail:
+         * <ul>
+         *     <li>dataType
+         *     <li>cardinality
+         * </ul>
+         *
+         * <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType}
+         * is also required.
          */
         public static final class Builder {
-            private final com.google.android.icing.proto.IndexingConfig.Builder mProtoBuilder =
-                    com.google.android.icing.proto.IndexingConfig.newBuilder();
+            private final PropertyConfigProto.Builder mPropertyConfigProto =
+                    PropertyConfigProto.newBuilder();
+            private final com.google.android.icing.proto.IndexingConfig.Builder
+                    mIndexingConfigProto =
+                        com.google.android.icing.proto.IndexingConfig.newBuilder();
 
-            private Builder() {}
+            private Builder(String propertyName) {
+                mPropertyConfigProto.setPropertyName(propertyName);
+            }
 
-            /** Configures how the content of this property should be matched in the index. */
+            /**
+             * Type of data the property contains (e.g. string, int, bytes, etc).
+             *
+             * <p>This property must be set.
+             */
             @NonNull
-            public IndexingConfig.Builder setTermMatchType(@TermMatchType int termMatchType) {
-                com.google.android.icing.proto.TermMatchType.Code termMatchTypeProto =
-                        com.google.android.icing.proto.TermMatchType.Code.forNumber(termMatchType);
-                if (termMatchTypeProto == null) {
-                    throw new IllegalArgumentException("Invalid termMatchType: " + termMatchType);
+            public PropertyConfig.Builder setDataType(@DataType int dataType) {
+                PropertyConfigProto.DataType.Code dataTypeProto =
+                        PropertyConfigProto.DataType.Code.forNumber(dataType);
+                if (dataTypeProto == null) {
+                    throw new IllegalArgumentException("Invalid dataType: " + dataType);
                 }
-                mProtoBuilder.setTermMatchType(termMatchTypeProto);
+                mPropertyConfigProto.setDataType(dataTypeProto);
+                return this;
+            }
+
+            /**
+             * The logical schema-type of the contents of this property.
+             *
+             * <p>Only required when {@link #setDataType(int)} is set to
+             * {@link #DATA_TYPE_DOCUMENT}. Otherwise, it is ignored.
+             */
+            @NonNull
+            public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
+                mPropertyConfigProto.setSchemaType(schemaType);
+                return this;
+            }
+
+            /**
+             * The cardinality of the property (whether it is optional, required or repeated).
+             *
+             * <p>This property must be set.
+             */
+            @NonNull
+            public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+                PropertyConfigProto.Cardinality.Code cardinalityProto =
+                        PropertyConfigProto.Cardinality.Code.forNumber(cardinality);
+                if (cardinalityProto == null) {
+                    throw new IllegalArgumentException("Invalid cardinality: " + cardinality);
+                }
+                mPropertyConfigProto.setCardinality(cardinalityProto);
+                return this;
+            }
+
+            /**
+             * Configures how a property should be indexed so that it can be retrieved by queries.
+             */
+            @NonNull
+            public PropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
+                TermMatchType.Code termMatchTypeProto;
+                switch (indexingType) {
+                    case INDEXING_TYPE_NONE:
+                        termMatchTypeProto = TermMatchType.Code.UNKNOWN;
+                        break;
+                    case INDEXING_TYPE_EXACT_TERMS:
+                        termMatchTypeProto = TermMatchType.Code.EXACT_ONLY;
+                        break;
+                    case INDEXING_TYPE_PREFIXES:
+                        termMatchTypeProto = TermMatchType.Code.PREFIX;
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Invalid indexingType: " + indexingType);
+                }
+                mIndexingConfigProto.setTermMatchType(termMatchTypeProto);
                 return this;
             }
 
             /** Configures how this property should be tokenized (split into words). */
             @NonNull
-            public IndexingConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
+            public PropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
                 com.google.android.icing.proto.IndexingConfig.TokenizerType.Code
                         tokenizerTypeProto =
                             com.google.android.icing.proto.IndexingConfig
-                                    .TokenizerType.Code.forNumber(tokenizerType);
+                                .TokenizerType.Code.forNumber(tokenizerType);
                 if (tokenizerTypeProto == null) {
                     throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType);
                 }
-                mProtoBuilder.setTokenizerType(tokenizerTypeProto);
+                mIndexingConfigProto.setTokenizerType(tokenizerTypeProto);
                 return this;
             }
 
             /**
-             * Constructs a new {@link IndexingConfig} from the contents of this builder.
+             * Constructs a new {@link PropertyConfig} from the contents of this builder.
              *
              * <p>After calling this method, the builder must no longer be used.
+             *
+             * @throws IllegalSchemaException If the property is not correctly populated (e.g.
+             *     missing {@code dataType}).
              */
             @NonNull
-            public IndexingConfig build() {
-                return new IndexingConfig(mProtoBuilder.build());
+            public PropertyConfig build() {
+                mPropertyConfigProto.setIndexingConfig(mIndexingConfigProto);
+                // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
+                //     of partially reimplementing some of the validation Icing does here.
+                if (mPropertyConfigProto.getDataType()
+                        == PropertyConfigProto.DataType.Code.UNKNOWN) {
+                    throw new IllegalSchemaException("Missing field: dataType");
+                }
+                if (mPropertyConfigProto.getSchemaType().isEmpty()
+                        && mPropertyConfigProto.getDataType()
+                            == PropertyConfigProto.DataType.Code.DOCUMENT) {
+                    throw new IllegalSchemaException(
+                            "Missing field: schemaType (required for configs with "
+                                    + "dataType = DOCUMENT)");
+                }
+                if (mPropertyConfigProto.getCardinality()
+                        == PropertyConfigProto.Cardinality.Code.UNKNOWN) {
+                    throw new IllegalSchemaException("Missing field: cardinality");
+                }
+                return new PropertyConfig(mPropertyConfigProto.build());
             }
         }
     }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 22250f4..20c8af98 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -17,18 +17,35 @@
 
 import com.android.internal.infra.AndroidFuture;
 
+parcelable AppSearchBatchResult;
+
 /** {@hide} */
 interface IAppSearchManager {
     /**
      * Sets the schema.
      *
-     * @param schemaProto serialized SchemaProto
+     * @param schemaBytes Serialized SchemaProto.
+     * @param forceOverride Whether to apply the new schema even if it is incompatible. All
+     *     incompatible documents will be deleted.
      * @param callback {@link AndroidFuture}&lt;{@link Void}&gt;. Will be completed with
-     *     {@code null} upon successful completion of the setSchema call, or completed exceptionally
-     *     if setSchema fails.
+     *     {@code null} upon successful completion of the setSchema call, or completed
+     *     exceptionally if setSchema fails.
      */
-    void setSchema(in byte[] schemaProto, in AndroidFuture callback);
-    void put(in byte[] documentBytes, in AndroidFuture callback);
+    void setSchema(in byte[] schemaBytes, boolean forceOverride, in AndroidFuture callback);
+
+    /**
+     * Inserts documents into the index.
+     *
+     * @param documentsBytes {@link List}&lt;byte[]&gt; of serialized DocumentProtos.
+     * @param callback
+     *     {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;&gt;.
+     *     If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
+     *     {@code callback} will be completed with an
+     *     {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
+     *     where the keys are document URIs, and the values are {@code null}.
+     */
+    void putDocuments(in List documentsBytes, in AndroidFuture<AppSearchBatchResult> callback);
+
     /**
      * Searches a document based on a given query string.
      *
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
index ec4258d..d763103 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java
@@ -60,7 +60,7 @@
         public AppSearch.Document getDocument() {
             return AppSearch.Document.newBuilder(mResultProto.getDocument().getUri(),
                     mResultProto.getDocument().getSchema())
-                    .setCreationTimestampSecs(mResultProto.getDocument().getCreationTimestampSecs())
+                    .setCreationTimestampMillis(mResultProto.getDocument().getCreationTimestampMs())
                     .setScore(mResultProto.getDocument().getScore())
                     .build();
         }
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 f63abd9..d2d9cf9 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -16,6 +16,7 @@
 package com.android.server.appsearch;
 
 import android.annotation.NonNull;
+import android.app.appsearch.AppSearchBatchResult;
 import android.app.appsearch.IAppSearchManager;
 import android.content.Context;
 import android.os.Binder;
@@ -28,11 +29,14 @@
 import com.android.server.appsearch.impl.FakeIcing;
 import com.android.server.appsearch.impl.ImplInstanceManager;
 
+import com.google.android.icing.proto.DocumentProto;
 import com.google.android.icing.proto.SchemaProto;
 import com.google.android.icing.proto.SearchResultProto;
 import com.google.android.icing.proto.SearchSpecProto;
 import com.google.android.icing.protobuf.InvalidProtocolBufferException;
 
+import java.util.List;
+
 /**
  * TODO(b/142567528): add comments when implement this class
  */
@@ -52,7 +56,7 @@
 
     private class Stub extends IAppSearchManager.Stub {
         @Override
-        public void setSchema(byte[] schemaBytes, AndroidFuture callback) {
+        public void setSchema(byte[] schemaBytes, boolean forceOverride, AndroidFuture callback) {
             Preconditions.checkNotNull(schemaBytes);
             Preconditions.checkNotNull(callback);
             int callingUid = Binder.getCallingUidOrThrow();
@@ -61,7 +65,7 @@
             try {
                 SchemaProto schema = SchemaProto.parseFrom(schemaBytes);
                 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
-                impl.setSchema(callingUid, schema);
+                impl.setSchema(callingUid, schema, forceOverride);
                 callback.complete(null);
             } catch (Throwable t) {
                 callback.completeExceptionally(t);
@@ -71,11 +75,32 @@
         }
 
         @Override
-        public void put(byte[] documentBytes, AndroidFuture callback) {
+        public void putDocuments(
+                List documentsBytes, AndroidFuture<AppSearchBatchResult> callback) {
+            Preconditions.checkNotNull(documentsBytes);
+            Preconditions.checkNotNull(callback);
+            int callingUid = Binder.getCallingUidOrThrow();
+            int callingUserId = UserHandle.getUserId(callingUid);
+            long callingIdentity = Binder.clearCallingIdentity();
             try {
-                throw new UnsupportedOperationException("Put document not yet implemented");
+                AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
+                AppSearchBatchResult.Builder<String, Void> resultBuilder =
+                        AppSearchBatchResult.newBuilder();
+                for (int i = 0; i < documentsBytes.size(); i++) {
+                    byte[] documentBytes = (byte[]) documentsBytes.get(i);
+                    DocumentProto document = DocumentProto.parseFrom(documentBytes);
+                    try {
+                        impl.putDocument(callingUid, document);
+                        resultBuilder.setSuccess(document.getUri(), /*value=*/ null);
+                    } catch (Throwable t) {
+                        resultBuilder.setFailure(document.getUri(), t);
+                    }
+                }
+                callback.complete(resultBuilder.build());
             } catch (Throwable t) {
                 callback.completeExceptionally(t);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
             }
         }
         // TODO(sidchhabra):Init FakeIcing properly.
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java
index 7c97b0b..04b4b14 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java
@@ -22,7 +22,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import com.google.android.icing.proto.DocumentProto;
 import com.google.android.icing.proto.PropertyConfigProto;
+import com.google.android.icing.proto.PropertyProto;
 import com.google.android.icing.proto.SchemaProto;
 import com.google.android.icing.proto.SchemaTypeConfigProto;
 
@@ -45,8 +47,10 @@
      *
      * @param callingUid The uid of the app calling AppSearch.
      * @param origSchema The schema to set for this app.
+     * @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
+     *     which do not comply with the new schema will be deleted.
      */
-    public void setSchema(int callingUid, @NonNull SchemaProto origSchema) {
+    public void setSchema(int callingUid, @NonNull SchemaProto origSchema, boolean forceOverride) {
         // Rewrite schema type names to include the calling app's package and uid.
         String typePrefix = getTypePrefix(callingUid);
         SchemaProto.Builder schemaBuilder = origSchema.toBuilder();
@@ -93,6 +97,60 @@
     }
 
     /**
+     * Adds a document to the AppSearch index.
+     *
+     * @param callingUid The uid of the app calling AppSearch.
+     * @param origDocument The document to index.
+     */
+    public void putDocument(int callingUid, @NonNull DocumentProto origDocument) {
+        // Rewrite the type names to include the app's prefix
+        String typePrefix = getTypePrefix(callingUid);
+        DocumentProto.Builder documentBuilder = origDocument.toBuilder();
+        rewriteDocumentTypes(typePrefix, documentBuilder);
+        mFakeIcing.put(documentBuilder.build());
+    }
+
+    /**
+     * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend
+     * {@code typePrefix}.
+     *
+     * @param typePrefix The prefix to add
+     * @param documentBuilder The document to mutate
+     */
+    @VisibleForTesting
+    void rewriteDocumentTypes(
+            @NonNull String typePrefix,
+            @NonNull DocumentProto.Builder documentBuilder) {
+        // Rewrite the type name to include the app's prefix
+        String newSchema = typePrefix + documentBuilder.getSchema();
+        documentBuilder.setSchema(newSchema);
+
+        // Add namespace. If we ever allow users to set their own namespaces, this will have
+        // to change to prepend the prefix instead of setting the whole namespace. We will also have
+        // to store the namespaces in a map similar to the type map so we can rewrite queries with
+        // empty namespaces.
+        documentBuilder.setNamespace(typePrefix);
+
+        // Recurse into derived documents
+        for (int propertyIdx = 0;
+                propertyIdx < documentBuilder.getPropertiesCount();
+                propertyIdx++) {
+            int documentCount = documentBuilder.getProperties(propertyIdx).getDocumentValuesCount();
+            if (documentCount > 0) {
+                PropertyProto.Builder propertyBuilder =
+                        documentBuilder.getProperties(propertyIdx).toBuilder();
+                for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) {
+                    DocumentProto.Builder derivedDocumentBuilder =
+                            propertyBuilder.getDocumentValues(documentIdx).toBuilder();
+                    rewriteDocumentTypes(typePrefix, derivedDocumentBuilder);
+                    propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder);
+                }
+                documentBuilder.setProperties(propertyIdx, propertyBuilder);
+            }
+        }
+    }
+
+   /**
      * Returns a type prefix in a format like {@code com.example.package@1000/} or
      * {@code com.example.sharedname:5678@1000/}.
      */
diff --git a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java b/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
similarity index 74%
copy from apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
copy to apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
index a534e22..02d0740 100644
--- a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -13,10 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package android.app.blob;
 
-package com.android.server.permission;
-
-/**
- * Persistence for runtime permissions.
- */
-public class RuntimePermissionPersistence {}
+/** {@hide} */
+parcelable BlobHandle;
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobHandle.java b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
new file mode 100644
index 0000000..6aca4a1
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
@@ -0,0 +1,187 @@
+/*
+ * 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.blob;
+
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * An identifier to represent a blob.
+ */
+// TODO: use datagen tool?
+public final class BlobHandle implements Parcelable {
+    private static final String ALGO_SHA_256 = "SHA-256";
+
+    private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters
+
+    /**
+     * Cyrptographically secure hash algorithm used to generate hash of the blob this handle is
+     * representing.
+     *
+     * @hide
+     */
+    @NonNull public final String algorithm;
+    /**
+     * Hash of the blob this handle is representing using {@link #algorithm}.
+     *
+     * @hide
+     */
+    @NonNull public final byte[] digest;
+    /**
+     * Label of the blob that can be surfaced to the user.
+     * @hide
+     */
+    @NonNull public final CharSequence label;
+    /**
+     * Time in milliseconds after which the blob should be invalidated and not
+     * allowed to be accessed by any other app, in {@link System#currentTimeMillis()} timebase.
+     *
+     * @hide
+     */
+    @CurrentTimeMillisLong public final long expiryTimeMillis;
+    /**
+     * An opaque {@link String} associated with the blob.
+     *
+     * @hide
+     */
+    @NonNull public final String tag;
+
+    private BlobHandle(String algorithm, byte[] digest, CharSequence label, long expiryTimeMillis,
+            String tag) {
+        this.algorithm = algorithm;
+        this.digest = digest;
+        this.label = label;
+        this.expiryTimeMillis = expiryTimeMillis;
+        this.tag = tag;
+    }
+
+    private BlobHandle(Parcel in) {
+        this.algorithm = in.readString();
+        this.digest = in.createByteArray();
+        this.label = in.readCharSequence();
+        this.expiryTimeMillis = in.readLong();
+        this.tag = in.readString();
+    }
+
+    /** @hide */
+    public static @NonNull BlobHandle create(@NonNull String algorithm, @NonNull byte[] digest,
+            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
+            @NonNull String tag) {
+        Preconditions.checkNotNull(algorithm, "algorithm must not be null");
+        Preconditions.checkNotNull(digest, "digest must not be null");
+        Preconditions.checkNotNull(label, "label must not be null");
+        Preconditions.checkArgumentNonnegative(expiryTimeMillis,
+                "expiryTimeMillis must not be negative");
+        Preconditions.checkNotNull(tag, "tag must not be null");
+        Preconditions.checkArgument(tag.length() <= LIMIT_BLOB_TAG_LENGTH, "tag too long");
+        return new BlobHandle(algorithm, digest, label, expiryTimeMillis, tag);
+    }
+
+    /**
+     * Create a new blob identifier.
+     *
+     * <p> For two objects of {@link BlobHandle} to be considered equal, the following arguments
+     * must be equal:
+     * <ul>
+     * <li> {@code digest}
+     * <li> {@code label}
+     * <li> {@code expiryTimeMillis}
+     * <li> {@code tag}
+     * </ul>
+     *
+     * @param digest the SHA-256 hash of the blob this is representing.
+     * @param label a label indicating what the blob is, that can be surfaced to the user.
+     * @param expiryTimeMillis the time in secs after which the blob should be invalidated and not
+     *                         allowed to be accessed by any other app,
+     *                         in {@link System#currentTimeMillis()} timebase.
+     * @param tag an opaque {@link String} associated with the blob. The length of the tag
+     *            cannot be more than 128 characters.
+     *
+     * @return a new instance of {@link BlobHandle} object.
+     */
+    public static @NonNull BlobHandle createWithSha256(@NonNull byte[] digest,
+            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
+            @NonNull String tag) {
+        return create(ALGO_SHA_256, digest, label, expiryTimeMillis, tag);
+    }
+
+    /**
+     * Returns the SHA-256 hash of the blob that this object is representing.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @NonNull byte[] getSha256Digest() {
+        return digest;
+    }
+
+    /**
+     * Returns the label associated with the blob that this object is representing.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @NonNull CharSequence getLabel() {
+        return label;
+    }
+
+    /**
+     * Returns the expiry time in milliseconds of the blob that this object is representing, in
+     *         {@link System#currentTimeMillis()} timebase.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @CurrentTimeMillisLong long getExpiryTimeMillis() {
+        return expiryTimeMillis;
+    }
+
+    /**
+     * Returns the opaque {@link String} associated with the blob this object is representing.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @NonNull String getTag() {
+        return tag;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(algorithm);
+        dest.writeByteArray(digest);
+        dest.writeCharSequence(label);
+        dest.writeLong(expiryTimeMillis);
+        dest.writeString(tag);
+    }
+
+    public static final @NonNull Creator<BlobHandle> CREATOR = new Creator<BlobHandle>() {
+        @Override
+        public @NonNull BlobHandle createFromParcel(@NonNull Parcel source) {
+            return new BlobHandle(source);
+        }
+
+        @Override
+        public @NonNull BlobHandle[] newArray(int size) {
+            return new BlobHandle[size];
+        }
+    };
+}
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 1ed188e..4395e5a 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -15,18 +15,33 @@
  */
 package android.app.blob;
 
+import android.annotation.BytesLong;
+import android.annotation.CallbackExecutor;
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.IdRes;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelableException;
+import android.os.RemoteException;
+
+import com.android.internal.util.function.pooled.PooledLambda;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
- * This class provides access to the blob store maintained by the system.
+ * This class provides access to the blob store managed by the system.
  *
  * Apps can publish data blobs which might be useful for other apps on the device to be
- * maintained by the system and apps that would like to access these data blobs can do so
+ * managed by the system and apps that would like to access these data blobs can do so
  * by addressing them via their cryptographically secure hashes.
  *
- * TODO: make this public once the APIs are added.
- * @hide
+ * TODO: More documentation.
  */
 @SystemService(Context.BLOB_STORE_SERVICE)
 public class BlobStoreManager {
@@ -34,8 +49,421 @@
     private final IBlobStoreManager mService;
 
     /** @hide */
-    public BlobStoreManager(Context context, IBlobStoreManager service) {
+    public BlobStoreManager(@NonNull Context context, @NonNull IBlobStoreManager service) {
         mContext = context;
         mService = service;
     }
+
+    /**
+     * Create a new session using the given {@link BlobHandle}, returning a unique id
+     * that represents the session. Once created, the session can be opened
+     * multiple times across multiple device boots.
+     *
+     * <p> The system may automatically destroy sessions that have not been
+     * finalized (either committed or abandoned) within a reasonable period of
+     * time, typically about a week.
+     *
+     * @param blobHandle the {@link BlobHandle} identifier for which a new session
+     *                   needs to be created.
+     * @return positive, non-zero unique id that represents the created session.
+     *         This id remains consistent across device reboots until the
+     *         session is finalized. IDs are not reused during a given boot.
+     *
+     * @throws IOException when there is an I/O error while creating the session.
+     * @throws SecurityException when the caller is not allowed to create a session, such
+     *                           as when called from an Instant app.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     * @throws IllegalStateException when a new session could not be created, such as when the
+     *                               caller is trying to create too many sessions or when the
+     *                               device is running low on space.
+     */
+    public @IntRange(from = 1) long createSession(@NonNull BlobHandle blobHandle)
+            throws IOException {
+        try {
+            return mService.createSession(blobHandle, mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Open an existing session to actively perform work.
+     *
+     * @param sessionId a unique id obtained via {@link #createSession(BlobHandle)} that
+     *                  represents a particular session.
+     * @return the {@link Session} object corresponding to the {@code sessionId}.
+     *
+     * @throws IOException when there is an I/O error while opening the session.
+     * @throws SecurityException when the caller does not own the session, or
+     *                           the session does not exist or is invalid.
+     */
+    public @NonNull Session openSession(@IntRange(from = 1) long sessionId) throws IOException {
+        try {
+            return new Session(mService.openSession(sessionId));
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Opens an existing blob for reading from the blob store managed by the system.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller
+     *                   wants to access.
+     * @return a {@link ParcelFileDescriptor} that can be used to read the blob content.
+     *
+     * @throws IOException when there is an I/O while opening the blob for read.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     */
+    public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
+            throws IOException {
+        try {
+            return mService.openBlob(blobHandle, mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the
+     * system that the caller wants the blob to be kept around.
+     *
+     * <p> Any active leases will be automatically released when the blob's expiry time
+     * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+     *                   acquire a lease for.
+     * @param descriptionResId the resource id for a short description string that can be surfaced
+     *                         to the user explaining what the blob is used for.
+     * @param leaseExpiryTimeMillis the time in milliseconds after which the lease can be
+     *                              automatically released, in {@link System#currentTimeMillis()}
+     *                              timebase. If its value is {@code 0}, then the behavior of this
+     *                              API is identical to {@link #acquireLease(BlobHandle, int)}
+     *                              where clients have to explicitly call
+     *                              {@link #releaseLease(BlobHandle)} when they don't
+     *                              need the blob anymore.
+     *
+     * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid or
+     *                                  if the {@code leaseExpiryTimeMillis} is greater than the
+     *                                  {@link BlobHandle#getExpiryTimeMillis()}.
+     * @throws IllegalStateException when a lease could not be acquired, such as when the
+     *                               caller is trying to acquire too many leases.
+     *
+     * @see {@link #acquireLease(BlobHandle, int)}
+     */
+    public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
+            @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
+        try {
+            mService.acquireLease(blobHandle, descriptionResId, leaseExpiryTimeMillis,
+                    mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the
+     * system that the caller wants the blob to be kept around.
+     *
+     * <p> This is similar to {@link #acquireLease(BlobHandle, int, long)} except clients don't
+     * have to specify the lease expiry time upfront using this API and need to explicitly
+     * release the lease using {@link #releaseLease(BlobHandle)} when they no longer like to keep
+     * a blob around.
+     *
+     * <p> Any active leases will be automatically released when the blob's expiry time
+     * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+     *                   acquire a lease for.
+     * @param descriptionResId the resource id for a short description string that can be surfaced
+     *                         to the user explaining what the blob is used for.
+     *
+     * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     * @throws IllegalStateException when a lease could not be acquired, such as when the
+     *                               caller is trying to acquire too many leases.
+     *
+     * @see {@link #acquireLease(BlobHandle, int, long)}
+     */
+    public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId)
+            throws IOException {
+        acquireLease(blobHandle, descriptionResId, 0);
+    }
+
+    /**
+     * Release all active leases to the blob represented by {@code blobHandle} which are
+     * currently held by the caller.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+     *                   release the leases for.
+     *
+     * @throws IOException when there is an I/O error while releasing the releases to the blob.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     */
+    public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
+        try {
+            mService.releaseLease(blobHandle, mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Represents an ongoing session of a blob's contribution to the blob store managed by the
+     * system.
+     *
+     * <p> Clients that want to contribute a blob need to first create a {@link Session} using
+     * {@link #createSession(BlobHandle)} and once the session is created, clients can open and
+     * close this session multiple times using {@link #openSession(long)} and
+     * {@link Session#close()} before committing it using
+     * {@link Session#commit(Executor, Consumer)}, at which point system will take
+     * ownership of the blob and the client can no longer make any modifications to the blob's
+     * content.
+     */
+    public static class Session implements Closeable {
+        private final IBlobStoreSession mSession;
+
+        private Session(@NonNull IBlobStoreSession session) {
+            mSession = session;
+        }
+
+        /**
+         * Opens a file descriptor to write a blob into the session.
+         *
+         * <p> The returned file descriptor will start writing data at the requested offset
+         * in the underlying file, which can be used to resume a partially
+         * written file. If a valid file length is specified, the system will
+         * preallocate the underlying disk space to optimize placement on disk.
+         * It is strongly recommended to provide a valid file length when known.
+         *
+         * @param offsetBytes offset into the file to begin writing at, or 0 to
+         *                    start at the beginning of the file.
+         * @param lengthBytes total size of the file being written, used to
+         *                    preallocate the underlying disk space, or -1 if unknown.
+         *                    The system may clear various caches as needed to allocate
+         *                    this space.
+         *
+         * @return a {@link ParcelFileDescriptor} for writing to the blob file.
+         *
+         * @throws IOException when there is an I/O error while opening the file to write.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to write to the file after it is
+         *                               abandoned (using {@link #abandon()})
+         *                               or committed (using {@link #commit})
+         *                               or closed (using {@link #close()}).
+         */
+        public @NonNull ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
+                @BytesLong long lengthBytes) throws IOException {
+            try {
+                return mSession.openWrite(offsetBytes, lengthBytes);
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Gets the size of the blob file that was written to the session so far.
+         *
+         * @return the size of the blob file so far.
+         *
+         * @throws IOException when there is an I/O error while opening the file to read.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to get the file size after it is
+         *                               abandoned (using {@link #abandon()})
+         *                               or closed (using {@link #close()}).
+         */
+        public @BytesLong long getSize() throws IOException {
+            try {
+                return mSession.getSize();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Close this session. It can be re-opened for writing/reading if it has not been
+         * abandoned (using {@link #abandon}) or closed (using {@link #commit}).
+         *
+         * @throws IOException when there is an I/O error while closing the session.
+         * @throws SecurityException when the caller is not the owner of the session.
+         */
+        public void close() throws IOException {
+            try {
+                mSession.close();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Abandon this session and delete any data that was written to this session so far.
+         *
+         * @throws IOException when there is an I/O error while abandoning the session.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to abandon a session which was
+         *                               already finalized.
+         */
+        public void abandon() throws IOException {
+            try {
+                mSession.abandon();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Allow {@code packageName} with a particular signing certificate to access this blob
+         * data once it is committed using a {@link BlobHandle} representing the blob.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * @param packageName the name of the package which should be allowed to access the blob.
+         * @param certificate the input bytes representing a certificate of type
+         *                    {@link android.content.pm.PackageManager#CERT_INPUT_SHA256}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowPackageAccess(@NonNull String packageName, @NonNull byte[] certificate)
+                throws IOException {
+            try {
+                mSession.allowPackageAccess(packageName, certificate);
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Allow packages which are signed with the same certificate as the caller to access this
+         * blob data once it is committed using a {@link BlobHandle} representing the blob.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowSameSignatureAccess() throws IOException {
+            try {
+                mSession.allowSameSignatureAccess();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Allow any app on the device to access this blob data once it is committed using
+         * a {@link BlobHandle} representing the blob.
+         *
+         * <p><strong>Note:</strong> This is only meant to be used from libraries and SDKs where
+         * the apps which we want to allow access is not known ahead of time.
+         * If a blob is being committed to be shared with a particular set of apps, it is highly
+         * recommended to use {@link #allowPackageAccess(String, byte[])} instead.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowPublicAccess() throws IOException {
+            try {
+                mSession.allowPublicAccess();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Commit the file that was written so far to this session to the blob store maintained by
+         * the system.
+         *
+         * <p> Once this method is called, the session is finalized and no additional
+         * mutations can be performed on the session. If the device reboots
+         * before the session has been finalized, you may commit the session again.
+         *
+         * <p> Note that this commit operation will fail if the hash of the data written so far
+         * to this session does not match with the one used for
+         * {@link BlobHandle#createWithSha256(byte[], CharSequence, long, String)}  BlobHandle}
+         * associated with this session.
+         *
+         * @param executor the executor on which result callback will be invoked.
+         * @param resultCallback a callback to receive the commit result. when the result is
+         *                       {@code 0}, it indicates success. Otherwise, failure.
+         *
+         * @throws IOException when there is an I/O error while committing the session.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalArgumentException when the passed parameters are not valid.
+         * @throws IllegalStateException when the caller tries to commit a session which was
+         *                               already finalized.
+         */
+        public void commit(@NonNull @CallbackExecutor Executor executor,
+                @NonNull Consumer<Integer> resultCallback) throws IOException {
+            try {
+                mSession.commit(new IBlobCommitCallback.Stub() {
+                    public void onResult(int result) {
+                        executor.execute(PooledLambda.obtainRunnable(
+                                Consumer::accept, resultCallback, result));
+                    }
+                });
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java b/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
similarity index 74%
rename from apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
rename to apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
index a534e22..a9b30e2 100644
--- a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -13,10 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package android.app.blob;
 
-package com.android.server.permission;
-
-/**
- * Persistence for runtime permissions.
- */
-public class RuntimePermissionPersistence {}
+/** {@hide} */
+oneway interface IBlobCommitCallback {
+    void onResult(int result);
+}
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index 00c1ed4..b7a2f1a 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -15,6 +15,16 @@
  */
 package android.app.blob;
 
+import android.app.blob.BlobHandle;
+import android.app.blob.IBlobStoreSession;
+
 /** {@hide} */
 interface IBlobStoreManager {
+    long createSession(in BlobHandle handle, in String packageName);
+    IBlobStoreSession openSession(long sessionId);
+    ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
+
+    void acquireLease(in BlobHandle handle, int descriptionResId, long leaseTimeout,
+            in String packageName);
+    void releaseLease(in BlobHandle handle, in String packageName);
 }
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
new file mode 100644
index 0000000..bb5ef3b
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.blob;
+
+import android.app.blob.IBlobCommitCallback;
+import android.os.ParcelFileDescriptor;
+
+/** {@hide} */
+interface IBlobStoreSession {
+    ParcelFileDescriptor openWrite(long offsetBytes, long lengthBytes);
+
+    void allowPackageAccess(in String packageName, in byte[] certificate);
+    void allowSameSignatureAccess();
+    void allowPublicAccess();
+
+    long getSize();
+    void close();
+    void abandon();
+
+    void commit(in IBlobCommitCallback callback);
+}
\ No newline at end of file
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index d7cab59..b204fee 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -15,8 +15,14 @@
  */
 package com.android.server.blob;
 
+import android.annotation.CurrentTimeSecondsLong;
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.app.blob.BlobHandle;
 import android.app.blob.IBlobStoreManager;
+import android.app.blob.IBlobStoreSession;
 import android.content.Context;
+import android.os.ParcelFileDescriptor;
 
 import com.android.server.SystemService;
 
@@ -25,8 +31,11 @@
  */
 public class BlobStoreManagerService extends SystemService {
 
+    private final Context mContext;
+
     public BlobStoreManagerService(Context context) {
         super(context);
+        mContext = context;
     }
 
     @Override
@@ -35,5 +44,29 @@
     }
 
     private class Stub extends IBlobStoreManager.Stub {
+        @Override
+        public long createSession(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+            return 0;
+        }
+
+        @Override
+        public IBlobStoreSession openSession(long sessionId) {
+            return null;
+        }
+
+        @Override
+        public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
+                @NonNull String packageName) {
+            return null;
+        }
+
+        @Override
+        public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
+                @CurrentTimeSecondsLong long leaseTimeout, @NonNull String packageName) {
+        }
+
+        @Override
+        public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+        }
     }
 }
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
new file mode 100644
index 0000000..2c38e76
--- /dev/null
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -0,0 +1,64 @@
+/*
+ * 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 com.android.server.blob;
+
+import android.annotation.BytesLong;
+import android.annotation.NonNull;
+import android.app.blob.IBlobCommitCallback;
+import android.app.blob.IBlobStoreSession;
+import android.os.ParcelFileDescriptor;
+
+/** TODO: add doc */
+public class BlobStoreSession extends IBlobStoreSession.Stub {
+
+    @Override
+    @NonNull
+    public ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
+            @BytesLong long lengthBytes) {
+        return null;
+    }
+
+    @Override
+    @BytesLong
+    public long getSize() {
+        return 0;
+    }
+
+    @Override
+    public void allowPackageAccess(@NonNull String packageName,
+            @NonNull byte[] certificate) {
+    }
+
+    @Override
+    public void allowSameSignatureAccess() {
+    }
+
+    @Override
+    public void allowPublicAccess() {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public void abandon() {
+    }
+
+    @Override
+    public void commit(IBlobCommitCallback callback) {
+    }
+}
diff --git a/apex/extservices/Android.bp b/apex/extservices/Android.bp
new file mode 100644
index 0000000..c89f694
--- /dev/null
+++ b/apex/extservices/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+apex {
+    name: "com.android.extservices",
+    defaults: ["com.android.extservices-defaults"],
+    manifest: "apex_manifest.json",
+}
+
+apex_defaults {
+    name: "com.android.extservices-defaults",
+    key: "com.android.extservices.key",
+    certificate: ":com.android.extservices.certificate",
+    apps: ["ExtServices"],
+}
+
+apex_key {
+    name: "com.android.extservices.key",
+    public_key: "com.android.extservices.avbpubkey",
+    private_key: "com.android.extservices.pem",
+}
+
+android_app_certificate {
+    name: "com.android.extservices.certificate",
+    certificate: "com.android.extservices",
+}
diff --git a/apex/extservices/apex_manifest.json b/apex/extservices/apex_manifest.json
new file mode 100644
index 0000000..7ba2157
--- /dev/null
+++ b/apex/extservices/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.extservices",
+  "version": 1
+}
diff --git a/apex/extservices/com.android.extservices.avbpubkey b/apex/extservices/com.android.extservices.avbpubkey
new file mode 100644
index 0000000..f37d3e4
--- /dev/null
+++ b/apex/extservices/com.android.extservices.avbpubkey
Binary files differ
diff --git a/apex/extservices/com.android.extservices.pem b/apex/extservices/com.android.extservices.pem
new file mode 100644
index 0000000..7bfbd34
--- /dev/null
+++ b/apex/extservices/com.android.extservices.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKAIBAAKCAgEAuYshVDiRkt3tmBhqcWkKOm5GcviKpLbHSPpYQDHGDwS0dqqL
+SqAd1/BgT/bVVtUkAciFApPnXn96WhNYCypptyC5FHCxM21uBCGmow+3WermD++w
+5dQk4QP2ONPIpG+KzOWBl9SiBud4SpOHDyr0JycBsrXS89Tln9kAsTDuDEFfXL/J
+8cX/S3IUwhPV0pAlgUIHdDp0DGFjZaJlEZBZ+HmImriC/AUNUMVb5lfbczXOEZPF
+0A9+JzYschfXUxn8nu1N7RN5GDbq+chszx1FMVhuFUheukkd4dLNSDl0O0RlUnD+
+C/xz1ilDzEVZhnMtMnxS9oJ8bA/HUVMfsFnaQbgGmQ0CcxFxnfbYyGXGG1H+b8vA
+MTVQi5rZXG2p+VgHIAKVrYmpETVnRPgoMqp18KuGtp5SDngi13G3YEzS7iFbqfYh
+6iW2G974nD/Dq0cSire8Oljd9PEaMCMZiP5PTFJp0G/mtw7ROoyZqsSM6rX3XVTo
+Y5dBmBMctSJ8rgDMi0ZNvRH+rq/E5+RT6yMAJ7DDbOJzBnQ3IIoGn8NzUT3P1FCB
+HYEp1U2N7QNirIQMAuVz3IlHae9N1kl3eGAO6f2CjV7vZmFpDeWw+KSYs71mRkOb
+WBgl6D9FFq4u1azrU3AwV0dj3x1eU6yVnKUy1J7ppF/mcR+VzH7ThzTdV7cCAwEA
+AQKCAgEApWFU2Mv/PYhg0bPZlLLKsiA+3RWaBo0AfpTd+oIjBpnr/OWweFjVoPcZ
+8cyShe4/RPOlUxHgJcO8m/MoA/PO/LLHJWf5GlzMthQEgs1sYVJVtBiydXitUn+E
+hUyIR8FAV7et1lZqAXtqJhbvSF7B9u/2vIMCv+GgtuTmkAmL9RKD3Jj6eG1CS84o
+oICrkx52v4rKOBgt/icEQMAKFCi1eRti3n3eCqK6JqdzbZIcAcoQnmw34mccy/im
+jx+fBuxf1oywa8NyqVmyAehazBVL6lrm7ENwY9zuLK4H2fuUFYu2QFCEsMxZt6da
+TgX2cTfSLnDQRfcyzeMWhu9vjHHabjpLNjiCKhIhGyO0rO1rtea8ajZHgM/2sxXq
+6gLynW0dlatlxmjANlN9WQPGNdzvcIFJ0TLnI4mlJnWpqCsN9iW1d4ey13WiZUVR
+DgtnR60zao+LRCCM4D3cuVLq0DjL2BlHGXnOPK/LpQG1LbI1TroZpgSEHSZlQRzT
+ql9txgNqTHxijXuPL2VhhwhW7cqDoO8sLwV3BqDMIH56U0cbUBiSA/G9fKeI/DEG
+i7LcrMgrBk+xnuAWoFHuzfBMAdD9i3kYyk+41tOmcza2TNJgxadVYp5woHFvYvS/
+GKaNiRz0XmcijO5Ir0yxgCq21BdkWzo5zVrTFABiKeR7YXiee8kCggEBAOeULWgR
+spolJJrACWJspRvKb9FGnbGiYOnCGJoAc751kuXmNxoyWnEwgcjrSEoayNPUfOtz
+IgA+twqjgl0Zec2XFPfUcgWUBrrvvUEV4NIH5ibaR7ezHGeovCWs9XoDyzHHvhDr
+c6T5kXFZ60rS5h6LGUnE1hkHFJoHuTIBbn9j7eIbri8S71i7HWQ04s4KuQ+Bwbxm
+UnkEhbc+zMWHXfXy7rx4/eEZcZwtEybIORcHXYNPGeqMfOlcEMHpKEOi+NvDA6cp
+vTaTSwJ6ZBgYh7Tw3bNgRxSknaIhcGwMD0ojStjC5xzXT1Zr2Z3GXwYvOGcq3MeZ
+z+V2cx5xuwyp7R0CggEBAM0cKKNZEZwi/1zBPUDMFB4iJoX12BxQX6e5wdlHGXgF
+XeZwCnaIxOxMDxH79M5Svmpdu/jkUijI/pRvcE1iohFyIBvTUSDmlAoy4keXqMEQ
+M2hA+TwVA3JLmMcV8HKy/MFlwwKJB1JDcoxGjnXsM5UjVTD2jilO7vlJZs3+0ws0
+R7qzRT3ED25QTpZyDYcKE2otc5bzIZG3yAaJtWd3NugWsKpxDgr2RFUGJiHBq72n
+48FkSjfgaDTn83zYcPvS0Uykb2ho8G/N+EurstL41n3nQo0I7FLbyptOopDDwsSp
+Ndejn08NVAQ+xFAafOyqHkA3Ytpl0QCZDpMBuLdvw+MCggEAOVMt1kgjPRMat4/4
+ArxANtvqyBRB7vnyIYthiaW5ARmbrntJgpuaVdCbIABWGbn9oqpD7gjHDuZ3axPE
+roUi6KiQkTSusQDOlbHI2Haw+2znJRD9ldSpoGNdh7oD3htYTk9Sll+ideEthrCq
+lRAV1NO8A83M7c8Z43Mr/dvq3XAAL+uIN7DpPL687NRGnJh87QDC039ExR5Ad3b9
+O5xhvwNO46rTtcgVnoJt7ji8IR46oMmQ8cWrGh0nLMkppWyPS98/ZT7ozryxYcCo
+TGquFTVWvBOGJO8G8l5ytNxbYI/R9Exy52nJAuyZpvu3BBHmVWt/0Y0asIOcxZmD
+owPhZQKCAQAfWAFBzReq05JQe1s/7q/YVwGqEQKgeQvVFsbvzDSxKajK0S5YJNhq
+/8iByA4GBZEBsidKhqGjh+uXhVwVB1Ca9+S+O9G3BGV1FYeMxzlLn40rjlpH+zIW
+okTLj6e5724+o61kUspioNn9Y77beGf9j3OyUsswttZAFB54tktL+AZKGqEnKjHt
+eqo3xWAZ1clXvXBfjfIAUaRok1y8XfRvDSCcO0CZHj8c+x6SpAT5q5FbeVb6KPnj
+s9p6ppzFbtb7Llm0C+1KOKCL98YRBWPJw7Bg2w86LkpM53xiQPgfk3gd5uwuaWwA
+ZhMb5qBWjjynNY+OrmZ8/+bBQk8XASZfAoIBAFkHOnZOD1JJQ0QvaJ9tuCgHi216
+I8QPMMTdm3ZEDHSYMNwl7ayeseBcmB2zaqBKYz75qcU0SK4lnZkR2wIpbsHZNSVM
+J0WpN6r9G4JdnVi11J04RsfSMjCUr/PTVMmPvw8xPHrCxkJmB+d56olSE80I1Jrx
+djCv1LtSsT10W7FIcY82/cOi4xxGLOA70lDCf+szofQgVP8WvuOA1YaFw98ca8zc
+A401CyNexk24/c3d6C19YW/MppdE0uGMxL/oHsPgwkZAf6LmvF/UF71PsBUEniLc
+YFaJl3wn1cPfBBo9L4sZzyP2qokL8YHdg+wW7b4IOsYwbeqceBvqPtcUUPs=
+-----END RSA PRIVATE KEY-----
diff --git a/apex/extservices/com.android.extservices.pk8 b/apex/extservices/com.android.extservices.pk8
new file mode 100644
index 0000000..59585a2
--- /dev/null
+++ b/apex/extservices/com.android.extservices.pk8
Binary files differ
diff --git a/apex/extservices/com.android.extservices.x509.pem b/apex/extservices/com.android.extservices.x509.pem
new file mode 100644
index 0000000..e0343b8
--- /dev/null
+++ b/apex/extservices/com.android.extservices.x509.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----
+MIIGLTCCBBWgAwIBAgIUdqdMmx/5OsCP3Ew3/hcr7+1ACHEwDQYJKoZIhvcNAQEL
+BQAwgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
+b2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEiMCAGCSqGSIb3
+DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAgFw0yMDAxMTcxMDIxMzZaGA80NzU3
+MTIxMzEwMjEzNlowgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
+MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
+VQQLDAdBbmRyb2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANKaSeLGaFRRt779vAtTfG3t2aQZrWOByUYc7yUN
+RdmJqWxU47OL5urYmanWPbz2f972Q9oi8x+8y4ny9SEY3wg0pUbzvKNTXpkxWyG1
+HE2C2zTfzuDDLpDIf2usWynt1wLVhpYC3k+7Yv2vOIK5dKkezh6PfdKmsbDae5DE
+d22tTSYZ5KwNpIWrgQle26cRG5sqhAFdkpgGMF00Huz06cjUoTjs2sNSlXTRBOTP
+CCy8UoRjBivQZkwHbddfsn+Z22ARPG8JDg/n4mEi8C0T6bJeQeirSPkBCkD6Djgq
+7RddJ2eLYZII8l8r6A6x+6cnTkXHaV5g3LUwPvi8XEn9IUuT9WJNRje/vfYLycTQ
+kP415CZMxDvsi1Ul4YsbL3enE89ryGMTpVZPogch/36DG5Sye28yISItNUy3urJa
+OXbg7mh+MwPd4bQaW4CJk+AUweKaF4aV0SZFT+nCewL4xLdGdy889KazlW98NqtK
+hOSxIg1jHkZq48ajuq2A+ns1yDKt1l0f9IYCz3mz/IXInokbkjPvHahJTJ+OMHXO
+THD8e5gBzcK841jJk+H3EsIYOHsp66uy2IgEHN+9pAS6vI0xfrXOYuKzuSL3oxcV
+FlVTimt4xokMMerdcW4KD+MC5NFEip4DUS4JKCyG0wRI3ffEs9Zcpxi3QSibrjLW
+rz+hAgMBAAGjUzBRMB0GA1UdDgQWBBTP2AhZzEUUgtAFlkaMaq+RvY06fDAfBgNV
+HSMEGDAWgBTP2AhZzEUUgtAFlkaMaq+RvY06fDAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBCwUAA4ICAQCbwtfo37j62Sudmt32PCfRN/r5ZNDNNA2JhR8uDUmX
+xXfF5YfDvSKsNLiQKcDagu6a+0C+QnzXHXCBlXZFrTJ8NAVMlmqdHGwoFoYMfJZH
+R1lCTidyFMoMLJ8GRGPJjzDkKnOeAqKMCtKvXoH2r12+JB2/ov4ooLREu/wPkEXT
+OymkyWNP5XLQTKWqfEQyXXFpuwZ+m35Wkr0Fm92mZeJpVeIZPK7M7aK3zyoj7XJP
+YLMsR/AQs8OULdpfNMddAuN3ndlYu03LZlsF6LG5bduaDDcESJ5hdJrgBa/NBKRU
+IbS+q/6WAjYKMNRT/fPGew4wUzlWKi1Ihdk79oaqKKijE1b2JSJD1/SEYiBf+JPE
+bXobUrMbBwFpdhT+YLMF9FsuPQKsUIONaWiO4QcQoY/rQwGxPP6fV8ZbBrUWJewj
+MpSdU9foZNa/TmOAgfS/JxH+nXnG4+H1m8mdNBsxvsYmF2ZuGb/jdEeA2cuHIJDZ
+FJeWwCFxzlCGZJaUsxsnZByADBuufUVaO/9gGs0YQC/JP1i9hK4DyZdKwZpXdLi2
+Nw27Qma4WEIZnMb6Rgk1nTV+7ALcOSIhGgFOOeDTuCGfnEcz2coai5fbD/K6Q7Xu
+IRNyxHQjheZPdei2x912Ex/KqKGfaFaZJxrvCSKdhzxcTFIsO4JuZs+SDpRTKcI7
+Cw==
+-----END CERTIFICATE-----
diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp
index 8b03da3..09571a1 100644
--- a/apex/permission/framework/Android.bp
+++ b/apex/permission/framework/Android.bp
@@ -26,7 +26,13 @@
     srcs: [
         ":framework-permission-sources",
     ],
-    sdk_version: "system_current",
+    // TODO(b/146758669): Use "system_current" after nullability annotations are system APIs.
+    sdk_version: "core_current",
+    libs: [
+        "framework-annotations-lib",
+        // TODO(b/146758669): Remove this line after nullability annotations are system APIs.
+        "android_system_stubs_current",
+    ],
     apex_available: [
         "com.android.permission",
         "test_com.android.permission",
diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp
index 972b362..4172e95 100644
--- a/apex/permission/service/Android.bp
+++ b/apex/permission/service/Android.bp
@@ -12,13 +12,24 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-java_library {
-    name: "service-permission",
+filegroup {
+    name: "service-permission-sources",
     srcs: [
         "java/**/*.java",
     ],
-    sdk_version: "system_current",
+}
+
+java_library {
+    name: "service-permission",
+    srcs: [
+        ":service-permission-sources",
+    ],
+    // TODO(b/146758669): Use "system_current" after nullability annotations are system APIs.
+    sdk_version: "core_current",
     libs: [
+        "framework-annotations-lib",
+        // TODO(b/146758669): Remove this line after nullability annotations are system APIs.
+        "android_system_stubs_current",
         "framework-permission",
     ],
     apex_available: [
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendCallback.java b/apex/permission/service/java/com/android/permission/persistence/IoUtils.java
similarity index 61%
copy from media/java/android/media/tv/tuner/frontend/FrontendCallback.java
copy to apex/permission/service/java/com/android/permission/persistence/IoUtils.java
index 9c4f460..0ae4460 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendCallback.java
+++ b/apex/permission/service/java/com/android/permission/persistence/IoUtils.java
@@ -14,17 +14,25 @@
  * limitations under the License.
  */
 
-package android.media.tv.tuner.frontend;
+package com.android.permission.persistence;
+
+import android.annotation.NonNull;
 
 /**
- * Frontend Callback.
- *
- * @hide
+ * Utility class for IO.
  */
-public interface FrontendCallback {
+public class IoUtils {
+
+    private IoUtils() {}
 
     /**
-     * Invoked when there is a frontend event.
+     * Close 'closeable' ignoring any exceptions.
      */
-    void onEvent(int frontendEventType);
+    public static void closeQuietly(@NonNull AutoCloseable closeable) {
+        try {
+            closeable.close();
+        } catch (Exception ignored) {
+            // Ignored.
+        }
+    }
 }
diff --git a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java
new file mode 100644
index 0000000..5f2d944
--- /dev/null
+++ b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permission.persistence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.UserHandle;
+
+/**
+ * Persistence for runtime permissions.
+ *
+ * TODO(b/147914847): Remove @hide when it becomes the default.
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES, process = SystemApi.Process.SYSTEM_SERVER)
+public interface RuntimePermissionsPersistence {
+
+    /**
+     * Read the runtime permissions from persistence.
+     *
+     * This will perform I/O operations synchronously.
+     *
+     * @param user the user to read for
+     * @return the runtime permissions read
+     */
+    @Nullable
+    RuntimePermissionsState read(@NonNull UserHandle user);
+
+    /**
+     * Write the runtime permissions to persistence.
+     *
+     * This will perform I/O operations synchronously.
+     *
+     * @param runtimePermissions the runtime permissions to write
+     * @param user the user to write for
+     */
+    void write(@NonNull RuntimePermissionsState runtimePermissions, @NonNull UserHandle user);
+
+    /**
+     * Delete the runtime permissions from persistence.
+     *
+     * This will perform I/O operations synchronously.
+     *
+     * @param user the user to delete for
+     */
+    void delete(@NonNull UserHandle user);
+
+    /**
+     * Create a new instance of {@link RuntimePermissionsPersistence} implementation.
+     *
+     * @return the new instance.
+     */
+    @NonNull
+    static RuntimePermissionsPersistence createInstance() {
+        return new RuntimePermissionsPersistenceImpl();
+    }
+}
diff --git a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java
new file mode 100644
index 0000000..51b911a
--- /dev/null
+++ b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permission.persistence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Persistence implementation for runtime permissions.
+ *
+ * TODO(b/147914847): Remove @hide when it becomes the default.
+ * @hide
+ */
+public class RuntimePermissionsPersistenceImpl implements RuntimePermissionsPersistence {
+
+    private static final String LOG_TAG = RuntimePermissionsPersistenceImpl.class.getSimpleName();
+
+    private static final String RUNTIME_PERMISSIONS_FILE_NAME = "runtime-permissions.xml";
+
+    private static final String TAG_PACKAGE = "package";
+    private static final String TAG_PERMISSION = "permission";
+    private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions";
+    private static final String TAG_SHARED_USER = "shared-user";
+
+    private static final String ATTRIBUTE_FINGERPRINT = "fingerprint";
+    private static final String ATTRIBUTE_FLAGS = "flags";
+    private static final String ATTRIBUTE_GRANTED = "granted";
+    private static final String ATTRIBUTE_NAME = "name";
+    private static final String ATTRIBUTE_VERSION = "version";
+
+    @Nullable
+    @Override
+    public RuntimePermissionsState read(@NonNull UserHandle user) {
+        File file = getFile(user);
+        try (FileInputStream inputStream = new AtomicFile(file).openRead()) {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(inputStream, null);
+            return parseXml(parser);
+        } catch (FileNotFoundException e) {
+            Log.i(LOG_TAG, "runtime-permissions.xml not found");
+            return null;
+        } catch (XmlPullParserException | IOException e) {
+            throw new IllegalStateException("Failed to read runtime-permissions.xml: " + file , e);
+        }
+    }
+
+    @NonNull
+    private static RuntimePermissionsState parseXml(@NonNull XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        int type;
+        int depth;
+        int innerDepth = parser.getDepth() + 1;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            if (parser.getName().equals(TAG_RUNTIME_PERMISSIONS)) {
+                return parseRuntimePermissions(parser);
+            }
+        }
+        throw new IllegalStateException("Missing <" + TAG_RUNTIME_PERMISSIONS
+                + "> in runtime-permissions.xml");
+    }
+
+    @NonNull
+    private static RuntimePermissionsState parseRuntimePermissions(@NonNull XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        String versionValue = parser.getAttributeValue(null, ATTRIBUTE_VERSION);
+        int version = versionValue != null ? Integer.parseInt(versionValue)
+                : RuntimePermissionsState.NO_VERSION;
+        String fingerprint = parser.getAttributeValue(null, ATTRIBUTE_FINGERPRINT);
+
+        Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
+                new ArrayMap<>();
+        Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
+                new ArrayMap<>();
+        int type;
+        int depth;
+        int innerDepth = parser.getDepth() + 1;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            switch (parser.getName()) {
+                case TAG_PACKAGE: {
+                    String packageName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
+                    List<RuntimePermissionsState.PermissionState> permissions = parsePermissions(
+                            parser);
+                    packagePermissions.put(packageName, permissions);
+                    break;
+                }
+                case TAG_SHARED_USER: {
+                    String sharedUserName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
+                    List<RuntimePermissionsState.PermissionState> permissions = parsePermissions(
+                            parser);
+                    sharedUserPermissions.put(sharedUserName, permissions);
+                    break;
+                }
+            }
+        }
+
+        return new RuntimePermissionsState(version, fingerprint, packagePermissions,
+                sharedUserPermissions);
+    }
+
+    @NonNull
+    private static List<RuntimePermissionsState.PermissionState> parsePermissions(
+            @NonNull XmlPullParser parser) throws IOException, XmlPullParserException {
+        List<RuntimePermissionsState.PermissionState> permissions = new ArrayList<>();
+        int type;
+        int depth;
+        int innerDepth = parser.getDepth() + 1;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            if (parser.getName().equals(TAG_PERMISSION)) {
+                String name = parser.getAttributeValue(null, ATTRIBUTE_NAME);
+                boolean granted = Boolean.parseBoolean(parser.getAttributeValue(null,
+                        ATTRIBUTE_GRANTED));
+                int flags = Integer.parseInt(parser.getAttributeValue(null,
+                        ATTRIBUTE_FLAGS), 16);
+                RuntimePermissionsState.PermissionState permission =
+                        new RuntimePermissionsState.PermissionState(name, granted, flags);
+                permissions.add(permission);
+            }
+        }
+        return permissions;
+    }
+
+    @Override
+    public void write(@NonNull RuntimePermissionsState runtimePermissions,
+            @NonNull UserHandle user) {
+        File file = getFile(user);
+        AtomicFile atomicFile = new AtomicFile(file);
+        FileOutputStream outputStream = null;
+        try {
+            outputStream = atomicFile.startWrite();
+
+            XmlSerializer serializer = Xml.newSerializer();
+            serializer.setOutput(outputStream, StandardCharsets.UTF_8.name());
+            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            serializer.startDocument(null, true);
+
+            serializeRuntimePermissions(serializer, runtimePermissions);
+
+            serializer.endDocument();
+            atomicFile.finishWrite(outputStream);
+        } catch (Exception e) {
+            Log.wtf(LOG_TAG, "Failed to write runtime-permissions.xml, restoring backup: " + file,
+                    e);
+            atomicFile.failWrite(outputStream);
+        } finally {
+            IoUtils.closeQuietly(outputStream);
+        }
+    }
+
+    private static void serializeRuntimePermissions(@NonNull XmlSerializer serializer,
+            @NonNull RuntimePermissionsState runtimePermissions) throws IOException {
+        serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
+
+        int version = runtimePermissions.getVersion();
+        serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
+        String fingerprint = runtimePermissions.getFingerprint();
+        if (fingerprint != null) {
+            serializer.attribute(null, ATTRIBUTE_FINGERPRINT, fingerprint);
+        }
+
+        for (Map.Entry<String, List<RuntimePermissionsState.PermissionState>> entry
+                : runtimePermissions.getPackagePermissions().entrySet()) {
+            String packageName = entry.getKey();
+            List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
+
+            serializer.startTag(null, TAG_PACKAGE);
+            serializer.attribute(null, ATTRIBUTE_NAME, packageName);
+            serializePermissions(serializer, permissions);
+            serializer.endTag(null, TAG_PACKAGE);
+        }
+
+        for (Map.Entry<String, List<RuntimePermissionsState.PermissionState>> entry
+                : runtimePermissions.getSharedUserPermissions().entrySet()) {
+            String sharedUserName = entry.getKey();
+            List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
+
+            serializer.startTag(null, TAG_SHARED_USER);
+            serializer.attribute(null, ATTRIBUTE_NAME, sharedUserName);
+            serializePermissions(serializer, permissions);
+            serializer.endTag(null, TAG_SHARED_USER);
+        }
+
+        serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
+    }
+
+    private static void serializePermissions(@NonNull XmlSerializer serializer,
+            @NonNull List<RuntimePermissionsState.PermissionState> permissions) throws IOException {
+        int permissionsSize = permissions.size();
+        for (int i = 0; i < permissionsSize; i++) {
+            RuntimePermissionsState.PermissionState permissionState = permissions.get(i);
+
+            serializer.startTag(null, TAG_PERMISSION);
+            serializer.attribute(null, ATTRIBUTE_NAME, permissionState.getName());
+            serializer.attribute(null, ATTRIBUTE_GRANTED, Boolean.toString(
+                    permissionState.isGranted()));
+            serializer.attribute(null, ATTRIBUTE_FLAGS, Integer.toHexString(
+                    permissionState.getFlags()));
+            serializer.endTag(null, TAG_PERMISSION);
+        }
+    }
+
+    @Override
+    public void delete(@NonNull UserHandle user) {
+        getFile(user).delete();
+    }
+
+    @NonNull
+    private static File getFile(@NonNull UserHandle user) {
+        // TODO: Use an API for this.
+        File dataDirectory = new File("/data/misc_de/" + user.getIdentifier()
+                + "/apexdata/com.android.permission");
+        return new File(dataDirectory, RUNTIME_PERMISSIONS_FILE_NAME);
+    }
+}
diff --git a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java
new file mode 100644
index 0000000..2a939e5
--- /dev/null
+++ b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.permission.persistence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * State of all runtime permissions.
+ *
+ * TODO(b/147914847): Remove @hide when it becomes the default.
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES, process = SystemApi.Process.SYSTEM_SERVER)
+public final class RuntimePermissionsState {
+
+    /**
+     * Special value for {@link #mVersion} to indicate that no version was read.
+     */
+    public static final int NO_VERSION = -1;
+
+    /**
+     * The version of the runtime permissions.
+     */
+    private final int mVersion;
+
+    /**
+     * The fingerprint of the runtime permissions.
+     */
+    @Nullable
+    private final String mFingerprint;
+
+    /**
+     * The runtime permissions by packages.
+     */
+    @NonNull
+    private final Map<String, List<PermissionState>> mPackagePermissions;
+
+    /**
+     * The runtime permissions by shared users.
+     */
+    @NonNull
+    private final Map<String, List<PermissionState>> mSharedUserPermissions;
+
+    public RuntimePermissionsState(int version, @Nullable String fingerprint,
+            @NonNull Map<String, List<PermissionState>> packagePermissions,
+            @NonNull Map<String, List<PermissionState>> sharedUserPermissions) {
+        mVersion = version;
+        mFingerprint = fingerprint;
+        mPackagePermissions = packagePermissions;
+        mSharedUserPermissions = sharedUserPermissions;
+    }
+
+    public int getVersion() {
+        return mVersion;
+    }
+
+    @Nullable
+    public String getFingerprint() {
+        return mFingerprint;
+    }
+
+    @NonNull
+    public Map<String, List<PermissionState>> getPackagePermissions() {
+        return mPackagePermissions;
+    }
+
+    @NonNull
+    public Map<String, List<PermissionState>> getSharedUserPermissions() {
+        return mSharedUserPermissions;
+    }
+
+    /**
+     * State of a single permission.
+     */
+    public static class PermissionState {
+
+        /**
+         * Name of the permission.
+         */
+        @NonNull
+        private final String mName;
+
+        /**
+         * Whether the permission is granted.
+         */
+        private final boolean mGranted;
+
+        /**
+         * Flags of the permission.
+         */
+        private final int mFlags;
+
+        public PermissionState(@NonNull String name, boolean granted, int flags) {
+            mName = name;
+            mGranted = granted;
+            mFlags = flags;
+        }
+
+        @NonNull
+        public String getName() {
+            return mName;
+        }
+
+        public boolean isGranted() {
+            return mGranted;
+        }
+
+        public int getFlags() {
+            return mFlags;
+        }
+    }
+}
diff --git a/apex/permission/service/java/com/android/role/persistence/RolesPersistence.java b/apex/permission/service/java/com/android/role/persistence/RolesPersistence.java
new file mode 100644
index 0000000..63c8eed
--- /dev/null
+++ b/apex/permission/service/java/com/android/role/persistence/RolesPersistence.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.role.persistence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.UserHandle;
+
+/**
+ * Persistence for roles.
+ *
+ * TODO(b/147914847): Remove @hide when it becomes the default.
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES, process = SystemApi.Process.SYSTEM_SERVER)
+public interface RolesPersistence {
+
+    /**
+     * Read the roles from persistence.
+     *
+     * This will perform I/O operations synchronously.
+     *
+     * @param user the user to read for
+     * @return the roles read
+     */
+    @Nullable
+    RolesState read(@NonNull UserHandle user);
+
+    /**
+     * Write the roles to persistence.
+     *
+     * This will perform I/O operations synchronously.
+     *
+     * @param roles the roles to write
+     * @param user the user to write for
+     */
+    void write(@NonNull RolesState roles, @NonNull UserHandle user);
+
+    /**
+     * Delete the roles from persistence.
+     *
+     * This will perform I/O operations synchronously.
+     *
+     * @param user the user to delete for
+     */
+    void delete(@NonNull UserHandle user);
+
+    /**
+     * Create a new instance of {@link RolesPersistence} implementation.
+     *
+     * @return the new instance.
+     */
+    @NonNull
+    static RolesPersistence createInstance() {
+        return new RolesPersistenceImpl();
+    }
+}
diff --git a/apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java b/apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java
new file mode 100644
index 0000000..5061742
--- /dev/null
+++ b/apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.role.persistence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.permission.persistence.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Persistence implementation for roles.
+ *
+ * TODO(b/147914847): Remove @hide when it becomes the default.
+ * @hide
+ */
+public class RolesPersistenceImpl implements RolesPersistence {
+
+    private static final String LOG_TAG = RolesPersistenceImpl.class.getSimpleName();
+
+    private static final String ROLES_FILE_NAME = "roles.xml";
+
+    private static final String TAG_ROLES = "roles";
+    private static final String TAG_ROLE = "role";
+    private static final String TAG_HOLDER = "holder";
+
+    private static final String ATTRIBUTE_VERSION = "version";
+    private static final String ATTRIBUTE_NAME = "name";
+    private static final String ATTRIBUTE_PACKAGES_HASH = "packagesHash";
+
+    @Nullable
+    @Override
+    public RolesState read(@NonNull UserHandle user) {
+        File file = getFile(user);
+        try (FileInputStream inputStream = new AtomicFile(file).openRead()) {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(inputStream, null);
+            return parseXml(parser);
+        } catch (FileNotFoundException e) {
+            Log.i(LOG_TAG, "roles.xml not found");
+            return null;
+        } catch (XmlPullParserException | IOException e) {
+            throw new IllegalStateException("Failed to read roles.xml: " + file , e);
+        }
+    }
+
+    @NonNull
+    private static RolesState parseXml(@NonNull XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        int type;
+        int depth;
+        int innerDepth = parser.getDepth() + 1;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            if (parser.getName().equals(TAG_ROLES)) {
+                return parseRoles(parser);
+            }
+        }
+        throw new IllegalStateException("Missing <" + TAG_ROLES + "> in roles.xml");
+    }
+
+    @NonNull
+    private static RolesState parseRoles(@NonNull XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        int version = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION));
+        String packagesHash = parser.getAttributeValue(null, ATTRIBUTE_PACKAGES_HASH);
+
+        Map<String, Set<String>> roles = new ArrayMap<>();
+        int type;
+        int depth;
+        int innerDepth = parser.getDepth() + 1;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            if (parser.getName().equals(TAG_ROLE)) {
+                String roleName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
+                Set<String> roleHolders = parseRoleHolders(parser);
+                roles.put(roleName, roleHolders);
+            }
+        }
+
+        return new RolesState(version, packagesHash, roles);
+    }
+
+    @NonNull
+    private static Set<String> parseRoleHolders(@NonNull XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        Set<String> roleHolders = new ArraySet<>();
+        int type;
+        int depth;
+        int innerDepth = parser.getDepth() + 1;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+            if (depth > innerDepth || type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            if (parser.getName().equals(TAG_HOLDER)) {
+                String roleHolder = parser.getAttributeValue(null, ATTRIBUTE_NAME);
+                roleHolders.add(roleHolder);
+            }
+        }
+        return roleHolders;
+    }
+
+    @Override
+    public void write(@NonNull RolesState roles,
+            @NonNull UserHandle user) {
+        File file = getFile(user);
+        AtomicFile atomicFile = new AtomicFile(file);
+        FileOutputStream outputStream = null;
+        try {
+            outputStream = atomicFile.startWrite();
+
+            XmlSerializer serializer = Xml.newSerializer();
+            serializer.setOutput(outputStream, StandardCharsets.UTF_8.name());
+            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            serializer.startDocument(null, true);
+
+            serializeRoles(serializer, roles);
+
+            serializer.endDocument();
+            atomicFile.finishWrite(outputStream);
+        } catch (Exception e) {
+            Log.wtf(LOG_TAG, "Failed to write roles.xml, restoring backup: " + file,
+                    e);
+            atomicFile.failWrite(outputStream);
+        } finally {
+            IoUtils.closeQuietly(outputStream);
+        }
+    }
+
+    private static void serializeRoles(@NonNull XmlSerializer serializer,
+            @NonNull RolesState roles) throws IOException {
+        serializer.startTag(null, TAG_ROLES);
+
+        int version = roles.getVersion();
+        serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
+        String packagesHash = roles.getPackagesHash();
+        if (packagesHash != null) {
+            serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+        }
+
+        for (Map.Entry<String, Set<String>> entry : roles.getRoles().entrySet()) {
+            String roleName = entry.getKey();
+            Set<String> roleHolders = entry.getValue();
+
+            serializer.startTag(null, TAG_ROLE);
+            serializer.attribute(null, ATTRIBUTE_NAME, roleName);
+            serializeRoleHolders(serializer, roleHolders);
+            serializer.endTag(null, TAG_ROLE);
+        }
+
+        serializer.endTag(null, TAG_ROLES);
+    }
+
+    private static void serializeRoleHolders(@NonNull XmlSerializer serializer,
+            @NonNull Set<String> roleHolders) throws IOException {
+        for (String roleHolder : roleHolders) {
+            serializer.startTag(null, TAG_HOLDER);
+            serializer.attribute(null, ATTRIBUTE_NAME, roleHolder);
+            serializer.endTag(null, TAG_HOLDER);
+        }
+    }
+
+    @Override
+    public void delete(@NonNull UserHandle user) {
+        getFile(user).delete();
+    }
+
+    @NonNull
+    private static File getFile(@NonNull UserHandle user) {
+        // TODO: Use an API for this.
+        File dataDirectory = new File("/data/misc_de/" + user.getIdentifier()
+                + "/apexdata/com.android.permission");
+        return new File(dataDirectory, ROLES_FILE_NAME);
+    }
+}
diff --git a/apex/permission/service/java/com/android/role/persistence/RolesState.java b/apex/permission/service/java/com/android/role/persistence/RolesState.java
new file mode 100644
index 0000000..bff980e
--- /dev/null
+++ b/apex/permission/service/java/com/android/role/persistence/RolesState.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.role.persistence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * State of all roles.
+ *
+ * TODO(b/147914847): Remove @hide when it becomes the default.
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES, process = SystemApi.Process.SYSTEM_SERVER)
+public final class RolesState {
+
+    /**
+     * The version of the roles.
+     */
+    private final int mVersion;
+
+    /**
+     * The hash of all packages in the system.
+     */
+    @Nullable
+    private final String mPackagesHash;
+
+    /**
+     * The roles.
+     */
+    @NonNull
+    private final Map<String, Set<String>> mRoles;
+
+    public RolesState(int version, @Nullable String packagesHash,
+            @NonNull Map<String, Set<String>> roles) {
+        mVersion = version;
+        mPackagesHash = packagesHash;
+        mRoles = roles;
+    }
+
+    public int getVersion() {
+        return mVersion;
+    }
+
+    @Nullable
+    public String getPackagesHash() {
+        return mPackagesHash;
+    }
+
+    @NonNull
+    public Map<String, Set<String>> getRoles() {
+        return mRoles;
+    }
+}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
index f8325d4..cc5172c6 100644
--- a/apex/statsd/aidl/Android.bp
+++ b/apex/statsd/aidl/Android.bp
@@ -23,7 +23,6 @@
         "android/os/IPullAtomResultReceiver.aidl",
         "android/os/IStatsCompanionService.aidl",
         "android/os/IStatsd.aidl",
-        "android/os/IStatsPullerCallback.aidl",
         "android/util/StatsEventParcel.aidl",
     ],
 }
diff --git a/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl b/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl
deleted file mode 100644
index c3e1e55..0000000
--- a/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.StatsLogEventWrapper;
-
-/**
-  * DEPRECATED
-  * Binder interface to pull atoms for the stats service.
-  * {@hide}
-  */
-interface IStatsPullerCallback {
-    /**
-     * Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing
-     * the data.
-     *
-     * Note: These pulled atoms should not have uid/attribution chain. Additionally, the event
-     * timestamps will be truncated to the nearest 5 minutes.
-     */
-    StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos);
-
-}
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
index 0ecf2f0..a2564212 100644
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ b/apex/statsd/aidl/android/os/IStatsd.aidl
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.os.IStatsPullerCallback;
 import android.os.IPendingIntentRef;
 import android.os.IPullAtomCallback;
 import android.os.ParcelFileDescriptor;
@@ -183,16 +182,6 @@
      */
     void sendAppBreadcrumbAtom(int label, int state);
 
-    /**
-     * Registers a puller callback function that, when invoked, pulls the data
-     * for the specified vendor atom tag.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
-     * @deprecated please use registerPullAtomCallback.
-     */
-    oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
-                                       String packageName);
-
    /**
     * Registers a puller callback function that, when invoked, pulls the data
     * for the specified atom tag.
@@ -207,13 +196,6 @@
     oneway void registerNativePullAtomCallback(int atomTag, long coolDownNs, long timeoutNs,
                            in int[] additiveFields, IPullAtomCallback pullerCallback);
 
-   /**
-    * Unregisters a puller callback function for the given vendor atom.
-    *
-    * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
-    */
-    oneway void unregisterPullerCallback(int atomTag, String packageName);
-
     /**
      * Unregisters any pullAtomCallback for the given uid/atom.
      */
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 17573bb..e5d1182 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -714,265 +714,6 @@
         }
     }
 
-    private void pullSystemElapsedRealtime(
-            int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeLong(SystemClock.elapsedRealtime());
-        pulledData.add(e);
-    }
-
-    private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        LooperStats looperStats = LocalServices.getService(LooperStats.class);
-        if (looperStats == null) {
-            throw new IllegalStateException("looperStats null");
-        }
-
-        List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
-        looperStats.reset();
-        for (LooperStats.ExportedEntry entry : entries) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(entry.workSourceUid);
-            e.writeString(entry.handlerClassName);
-            e.writeString(entry.threadName);
-            e.writeString(entry.messageName);
-            e.writeLong(entry.messageCount);
-            e.writeLong(entry.exceptionCount);
-            e.writeLong(entry.recordedMessageCount);
-            e.writeLong(entry.totalLatencyMicros);
-            e.writeLong(entry.cpuUsageMicros);
-            e.writeBoolean(entry.isInteractive);
-            e.writeLong(entry.maxCpuUsageMicros);
-            e.writeLong(entry.maxLatencyMicros);
-            e.writeLong(entry.recordedDelayMessageCount);
-            e.writeLong(entry.delayMillis);
-            e.writeLong(entry.maxDelayMillis);
-            pulledData.add(e);
-        }
-    }
-
-    private void pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        // Run a quick-and-dirty performance test: write 512 bytes
-        byte[] junk = new byte[512];
-        for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
-
-        File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
-        FileOutputStream fos = null;
-        IOException error = null;
-
-        long before = SystemClock.elapsedRealtime();
-        try {
-            fos = new FileOutputStream(tmp);
-            fos.write(junk);
-        } catch (IOException e) {
-            error = e;
-        } finally {
-            try {
-                if (fos != null) fos.close();
-            } catch (IOException e) {
-                // Do nothing.
-            }
-        }
-
-        long latency = SystemClock.elapsedRealtime() - before;
-        if (tmp.exists()) tmp.delete();
-
-        if (error != null) {
-            Slog.e(TAG, "Error performing diskstats latency test");
-            latency = -1;
-        }
-        // File based encryption.
-        boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
-
-        //Recent disk write speed. Binder call to storaged.
-        int writeSpeed = -1;
-        try {
-            IBinder binder = ServiceManager.getService("storaged");
-            if (binder == null) {
-                Slog.e(TAG, "storaged not found");
-            }
-            IStoraged storaged = IStoraged.Stub.asInterface(binder);
-            writeSpeed = storaged.getRecentPerf();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "storaged not found");
-        }
-
-        // Add info pulledData.
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeLong(latency);
-        e.writeBoolean(fileBased);
-        e.writeInt(writeSpeed);
-        pulledData.add(e);
-    }
-
-    private void pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
-        StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
-        StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
-
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA);
-        e.writeLong(statFsData.getAvailableBytes());
-        e.writeLong(statFsData.getTotalBytes());
-        pulledData.add(e);
-
-        e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE);
-        e.writeLong(statFsCache.getAvailableBytes());
-        e.writeLong(statFsCache.getTotalBytes());
-        pulledData.add(e);
-
-        e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM);
-        e.writeLong(statFsSystem.getAvailableBytes());
-        e.writeLong(statFsSystem.getTotalBytes());
-        pulledData.add(e);
-    }
-
-    private void pullAppSize(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        try {
-            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
-            JSONObject json = new JSONObject(jsonStr);
-            long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
-            JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
-            JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
-            JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
-            JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
-            // Sanity check: Ensure all 4 lists have the same length.
-            int length = pkg_names.length();
-            if (app_sizes.length() != length || app_data_sizes.length() != length
-                    || app_cache_sizes.length() != length) {
-                Slog.e(TAG, "formatting error in diskstats cache file!");
-                return;
-            }
-            for (int i = 0; i < length; i++) {
-                StatsLogEventWrapper e =
-                        new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                e.writeString(pkg_names.getString(i));
-                e.writeLong(app_sizes.optLong(i, -1L));
-                e.writeLong(app_data_sizes.optLong(i, -1L));
-                e.writeLong(app_cache_sizes.optLong(i, -1L));
-                e.writeLong(cache_time);
-                pulledData.add(e);
-            }
-        } catch (IOException | JSONException e) {
-            Slog.e(TAG, "exception reading diskstats cache file", e);
-        }
-    }
-
-    private void pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        try {
-            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
-            JSONObject json = new JSONObject(jsonStr);
-            long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
-
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE);
-            e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE);
-            e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE);
-            e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS);
-            e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS);
-            e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO);
-            e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS);
-            e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM);
-            e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER);
-            e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-        } catch (IOException | JSONException e) {
-            Slog.e(TAG, "exception reading diskstats cache file", e);
-        }
-    }
-
-    private void pullNumBiometricsEnrolled(int modality, int tagId, long elapsedNanos,
-            long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
-        final PackageManager pm = mContext.getPackageManager();
-        FingerprintManager fingerprintManager = null;
-        FaceManager faceManager = null;
-
-        if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
-            fingerprintManager = mContext.getSystemService(
-                    FingerprintManager.class);
-        }
-        if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
-            faceManager = mContext.getSystemService(FaceManager.class);
-        }
-
-        if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
-            return;
-        }
-        if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
-            return;
-        }
-        UserManager userManager = mContext.getSystemService(UserManager.class);
-        if (userManager == null) {
-            return;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        for (UserInfo user : userManager.getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-            int numEnrolled = 0;
-            if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
-                numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
-            } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
-                numEnrolled = faceManager.getEnrolledFaces(userId).size();
-            } else {
-                return;
-            }
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(userId);
-            e.writeInt(numEnrolled);
-            pulledData.add(e);
-        }
-        Binder.restoreCallingIdentity(token);
-    }
-
     // read high watermark for section
     private long readProcStatsHighWaterMark(int section) {
         try {
@@ -1024,39 +765,6 @@
         }
     }
 
-    private INotificationManager mNotificationManager =
-            INotificationManager.Stub.asInterface(
-                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-
-    private void pullNotificationStats(int reportId, int tagId, long elapsedNanos,
-            long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        final long callingToken = Binder.clearCallingIdentity();
-        try {
-            // determine last pull tine. Copy file trick from pullProcessStats?
-            long lastNotificationStatsNs = wallClockNanos -
-                    TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
-
-            List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
-            long notificationStatsNs = mNotificationManager.pullStats(
-                    lastNotificationStatsNs, reportId, true, statsFiles);
-            if (statsFiles.size() != 1) {
-                return;
-            }
-            unpackStreamedData(tagId, elapsedNanos, wallClockNanos, pulledData, statsFiles);
-        } catch (IOException e) {
-            Log.e(TAG, "Getting notistats failed: ", e);
-
-        } catch (RemoteException e) {
-            Log.e(TAG, "Getting notistats failed: ", e);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Getting notistats failed: ", e);
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-
-    }
-
     static void unpackStreamedData(int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData, List<ParcelFileDescriptor> statsFiles)
             throws IOException {
@@ -1098,104 +806,6 @@
         }
     }
 
-    private void pullDiskIo(int tagId, long elapsedNanos, final long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
-                fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
-                fgFsync, bgFsync) -> {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
-                    wallClockNanos);
-            e.writeInt(uid);
-            e.writeLong(fgCharsRead);
-            e.writeLong(fgCharsWrite);
-            e.writeLong(fgBytesRead);
-            e.writeLong(fgBytesWrite);
-            e.writeLong(bgCharsRead);
-            e.writeLong(bgCharsWrite);
-            e.writeLong(bgBytesRead);
-            e.writeLong(bgBytesWrite);
-            e.writeLong(fgFsync);
-            e.writeLong(bgFsync);
-            pulledData.add(e);
-        });
-    }
-
-    private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        synchronized (this) {
-            if (mProcessCpuTracker == null) {
-                mProcessCpuTracker = new ProcessCpuTracker(false);
-                mProcessCpuTracker.init();
-            }
-            mProcessCpuTracker.update();
-            for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
-                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
-                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
-                        wallClockNanos);
-                e.writeInt(st.uid);
-                e.writeString(st.name);
-                e.writeLong(st.base_utime);
-                e.writeLong(st.base_stime);
-                pulledData.add(e);
-            }
-        }
-    }
-
-    private void pullCpuTimePerThreadFreq(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        if (this.mKernelCpuThreadReader == null) {
-            throw new IllegalStateException("mKernelCpuThreadReader is null");
-        }
-        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
-                this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
-        if (processCpuUsages == null) {
-            throw new IllegalStateException("processCpuUsages is null");
-        }
-        int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
-        if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
-            String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
-                    + " frequencies, but got " + cpuFrequencies.length;
-            Slog.w(TAG, message);
-            throw new IllegalStateException(message);
-        }
-        for (int i = 0; i < processCpuUsages.size(); i++) {
-            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
-            ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
-                    processCpuUsage.threadCpuUsages;
-            for (int j = 0; j < threadCpuUsages.size(); j++) {
-                KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
-                if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
-                    String message = "Unexpected number of usage times,"
-                            + " expected " + cpuFrequencies.length
-                            + " but got " + threadCpuUsage.usageTimesMillis.length;
-                    Slog.w(TAG, message);
-                    throw new IllegalStateException(message);
-                }
-
-                StatsLogEventWrapper e =
-                        new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                e.writeInt(processCpuUsage.uid);
-                e.writeInt(processCpuUsage.processId);
-                e.writeInt(threadCpuUsage.threadId);
-                e.writeString(processCpuUsage.processName);
-                e.writeString(threadCpuUsage.threadName);
-                for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
-                    if (k < cpuFrequencies.length) {
-                        e.writeInt(cpuFrequencies[k]);
-                        e.writeInt(threadCpuUsage.usageTimesMillis[k]);
-                    } else {
-                        // If we have no more frequencies to write, we still must write empty data.
-                        // We know that this data is empty (and not just zero) because all
-                        // frequencies are expected to be greater than zero
-                        e.writeInt(0);
-                        e.writeInt(0);
-                    }
-                }
-                pulledData.add(e);
-            }
-        }
-    }
-
     private void pullDebugElapsedClock(int tagId,
             long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
         final long elapsedMillis = SystemClock.elapsedRealtime();
@@ -1246,283 +856,6 @@
         pulledData.add(e);
     }
 
-    private void pullDangerousPermissionState(int atomId, long elapsedNanos,
-            final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
-        long token = Binder.clearCallingIdentity();
-        Set<Integer> reportedUids = new HashSet<>();
-        try {
-            PackageManager pm = mContext.getPackageManager();
-
-            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
-
-            int numUsers = users.size();
-            for (int userNum = 0; userNum < numUsers; userNum++) {
-                UserHandle user = users.get(userNum).getUserHandle();
-
-                List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
-                        PackageManager.GET_PERMISSIONS, user.getIdentifier());
-
-                int numPkgs = pkgs.size();
-                for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
-                    PackageInfo pkg = pkgs.get(pkgNum);
-
-                    if (pkg.requestedPermissions == null) {
-                        continue;
-                    }
-
-                    if (reportedUids.contains(pkg.applicationInfo.uid)) {
-                        // do not report same uid twice
-                        continue;
-                    }
-                    reportedUids.add(pkg.applicationInfo.uid);
-
-                    if (atomId == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
-                            && ThreadLocalRandom.current().nextFloat() > 0.2f) {
-                        continue;
-                    }
-
-                    int numPerms = pkg.requestedPermissions.length;
-                    for (int permNum  = 0; permNum < numPerms; permNum++) {
-                        String permName = pkg.requestedPermissions[permNum];
-
-                        PermissionInfo permissionInfo;
-                        int permissionFlags = 0;
-                        try {
-                            permissionInfo = pm.getPermissionInfo(permName, 0);
-                            permissionFlags =
-                                    pm.getPermissionFlags(permName, pkg.packageName, user);
-
-                        } catch (PackageManager.NameNotFoundException ignored) {
-                            continue;
-                        }
-
-                        if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
-                            continue;
-                        }
-
-                        StatsLogEventWrapper e = new StatsLogEventWrapper(
-                                atomId, elapsedNanos, wallClockNanos);
-
-                        e.writeString(permName);
-                        e.writeInt(pkg.applicationInfo.uid);
-                        if (atomId == StatsLog.DANGEROUS_PERMISSION_STATE) {
-                            e.writeString(null);
-                        }
-                        e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
-                                & REQUESTED_PERMISSION_GRANTED) != 0);
-                        e.writeInt(permissionFlags);
-
-                        pulledData.add(e);
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "Could not read permissions", t);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    private void pullAppOps(long elapsedNanos, final long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        long token = Binder.clearCallingIdentity();
-        try {
-            AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
-
-            CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
-            HistoricalOpsRequest histOpsRequest =
-                    new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).build();
-            appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
-
-            HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
-                    TimeUnit.MILLISECONDS);
-
-            for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
-                final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
-                final int uid = uidOps.getUid();
-                for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
-                    final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
-                    for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
-                        final AppOpsManager.HistoricalOp op  = packageOps.getOpAt(opIdx);
-                        StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS,
-                                elapsedNanos, wallClockNanos);
-
-                        e.writeInt(uid);
-                        e.writeString(packageOps.getPackageName());
-                        e.writeInt(op.getOpCode());
-                        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
-
-                        String perm = AppOpsManager.opToPermission(op.getOpCode());
-                        if (perm == null) {
-                            e.writeBoolean(false);
-                        } else {
-                            PermissionInfo permInfo;
-                            try {
-                                permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
-                                e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
-                            } catch (PackageManager.NameNotFoundException exception) {
-                                e.writeBoolean(false);
-                            }
-                        }
-
-                        pulledData.add(e);
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "Could not read appops", t);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-
-    /**
-     * Add a RoleHolder atom for each package that holds a role.
-     *
-     * @param elapsedNanos the time since boot
-     * @param wallClockNanos the time on the clock
-     * @param pulledData the data sink to write to
-     */
-    private void pullRoleHolders(long elapsedNanos, final long wallClockNanos,
-            @NonNull List<StatsLogEventWrapper> pulledData) {
-        long callingToken = Binder.clearCallingIdentity();
-        try {
-            PackageManager pm = mContext.getPackageManager();
-            RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
-
-            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
-
-            int numUsers = users.size();
-            for (int userNum = 0; userNum < numUsers; userNum++) {
-                int userId = users.get(userNum).getUserHandle().getIdentifier();
-
-                ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(
-                        userId);
-
-                int numRoles = roles.size();
-                for (int roleNum = 0; roleNum < numRoles; roleNum++) {
-                    String roleName = roles.keyAt(roleNum);
-                    ArraySet<String> holders = roles.valueAt(roleNum);
-
-                    int numHolders = holders.size();
-                    for (int holderNum = 0; holderNum < numHolders; holderNum++) {
-                        String holderName = holders.valueAt(holderNum);
-
-                        PackageInfo pkg;
-                        try {
-                            pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
-                        } catch (PackageManager.NameNotFoundException e) {
-                            Log.w(TAG, "Role holder " + holderName + " not found");
-                            return;
-                        }
-
-                        StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.ROLE_HOLDER,
-                                elapsedNanos, wallClockNanos);
-                        e.writeInt(pkg.applicationInfo.uid);
-                        e.writeString(holderName);
-                        e.writeString(roleName);
-                        pulledData.add(e);
-                    }
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-    }
-
-    private void pullTimeZoneDataInfo(int tagId,
-            long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
-        String tzDbVersion = "Unknown";
-        try {
-            tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
-        } catch (Exception e) {
-            Log.e(TAG, "Getting tzdb version failed: ", e);
-        }
-
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeString(tzDbVersion);
-        pulledData.add(e);
-    }
-
-    private void pullExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        StorageManager storageManager = mContext.getSystemService(StorageManager.class);
-        if (storageManager != null) {
-            List<VolumeInfo> volumes = storageManager.getVolumes();
-            for (VolumeInfo vol : volumes) {
-                final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
-                final DiskInfo diskInfo = vol.getDisk();
-                if (diskInfo != null) {
-                    if (envState.equals(Environment.MEDIA_MOUNTED)) {
-                        // Get the type of the volume, if it is adoptable or portable.
-                        int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
-                        if (vol.getType() == TYPE_PUBLIC) {
-                            volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
-                        } else if (vol.getType() == TYPE_PRIVATE) {
-                            volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
-                        }
-                        // Get the type of external storage inserted in the device (sd cards,
-                        // usb, etc)
-                        int externalStorageType;
-                        if (diskInfo.isSd()) {
-                            externalStorageType = StorageEnums.SD_CARD;
-                        } else if (diskInfo.isUsb()) {
-                            externalStorageType = StorageEnums.USB;
-                        } else {
-                            externalStorageType = StorageEnums.OTHER;
-                        }
-                        StatsLogEventWrapper e =
-                                new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                        e.writeInt(externalStorageType);
-                        e.writeInt(volumeType);
-                        e.writeLong(diskInfo.size);
-                        pulledData.add(e);
-                    }
-                }
-            }
-        }
-    }
-
-    private void pullAppsOnExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        PackageManager pm = mContext.getPackageManager();
-        StorageManager storage = mContext.getSystemService(StorageManager.class);
-        List<ApplicationInfo> apps = pm.getInstalledApplications(/* flags = */ 0);
-        for (ApplicationInfo appInfo : apps) {
-            UUID storageUuid = appInfo.storageUuid;
-            if (storageUuid != null) {
-                VolumeInfo volumeInfo = storage.findVolumeByUuid(appInfo.storageUuid.toString());
-                if (volumeInfo != null) {
-                    DiskInfo diskInfo = volumeInfo.getDisk();
-                    if (diskInfo != null) {
-                        int externalStorageType = -1;
-                        if (diskInfo.isSd()) {
-                            externalStorageType = StorageEnums.SD_CARD;
-                        } else if (diskInfo.isUsb()) {
-                            externalStorageType = StorageEnums.USB;
-                        } else if (appInfo.isExternal()) {
-                            externalStorageType = StorageEnums.OTHER;
-                        }
-                        // App is installed on external storage.
-                        if (externalStorageType != -1) {
-                            StatsLogEventWrapper e =
-                                    new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                            e.writeInt(externalStorageType);
-                            e.writeString(appInfo.packageName);
-                            pulledData.add(e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
     private void pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
         long callingToken = Binder.clearCallingIdentity();
@@ -1574,48 +907,6 @@
         long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
         switch (tagId) {
 
-            case StatsLog.SYSTEM_ELAPSED_REALTIME: {
-                pullSystemElapsedRealtime(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.LOOPER_STATS: {
-                pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DISK_STATS: {
-                pullDiskStats(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DIRECTORY_USAGE: {
-                pullDirectoryUsage(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.APP_SIZE: {
-                pullAppSize(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.CATEGORY_SIZE: {
-                pullCategorySize(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.NUM_FINGERPRINTS_ENROLLED: {
-                pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FINGERPRINT, tagId,
-                        elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.NUM_FACES_ENROLLED: {
-                pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FACE, tagId, elapsedNanos,
-                        wallClockNanos, ret);
-                break;
-            }
-
             case StatsLog.PROC_STATS: {
                 pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret);
                 break;
@@ -1627,20 +918,6 @@
                 break;
             }
 
-            case StatsLog.DISK_IO: {
-                pullDiskIo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.PROCESS_CPU_TIME: {
-                pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-            case StatsLog.CPU_TIME_PER_THREAD_FREQ: {
-                pullCpuTimePerThreadFreq(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
             case StatsLog.DEBUG_ELAPSED_CLOCK: {
                 pullDebugElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
@@ -1651,54 +928,11 @@
                 break;
             }
 
-            case StatsLog.ROLE_HOLDER: {
-                pullRoleHolders(elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DANGEROUS_PERMISSION_STATE: {
-                pullDangerousPermissionState(StatsLog.DANGEROUS_PERMISSION_STATE, elapsedNanos,
-                        wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED: {
-                pullDangerousPermissionState(StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED,
-                        elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.TIME_ZONE_DATA_INFO: {
-                pullTimeZoneDataInfo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.EXTERNAL_STORAGE_INFO: {
-                pullExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: {
-                pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
             case StatsLog.FACE_SETTINGS: {
                 pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
 
-            case StatsLog.APP_OPS: {
-                pullAppOps(elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.NOTIFICATION_REMOTE_VIEWS: {
-                pullNotificationStats(NotificationManagerService.REPORT_REMOTE_VIEWS,
-                        tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
             default:
                 Slog.w(TAG, "No such tagId data as " + tagId);
                 return null;
diff --git a/api/current.txt b/api/current.txt
index 92a89e6..1c03c23 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2854,6 +2854,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
     method @NonNull public final android.accessibilityservice.AccessibilityService.SoftKeyboardController getSoftKeyboardController();
+    method @NonNull public final java.util.List<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> getSystemActions();
     method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
     method @NonNull public final android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
     method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
@@ -2863,6 +2864,7 @@
     method public abstract void onInterrupt();
     method protected boolean onKeyEvent(android.view.KeyEvent);
     method protected void onServiceConnected();
+    method public void onSystemActionsChanged();
     method public final boolean performGlobalAction(int);
     method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
     method public boolean takeScreenshot(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.graphics.Bitmap>);
@@ -3975,6 +3977,7 @@
     method public android.util.Size getAppTaskThumbnailSize();
     method public java.util.List<android.app.ActivityManager.AppTask> getAppTasks();
     method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
+    method @Nullable public java.util.List<android.app.ApplicationExitInfo> getHistoricalProcessExitReasons(@Nullable String, @IntRange(from=0) int, @IntRange(from=0) int);
     method public int getLargeMemoryClass();
     method public int getLauncherLargeIconDensity();
     method public int getLauncherLargeIconSize();
@@ -3992,6 +3995,7 @@
     method public boolean isActivityStartAllowedOnDisplay(@NonNull android.content.Context, int, @NonNull android.content.Intent);
     method public boolean isBackgroundRestricted();
     method @Deprecated public boolean isInLockTaskMode();
+    method public static boolean isLowMemoryKillReportSupported();
     method public boolean isLowRamDevice();
     method @Deprecated public static boolean isRunningInTestHarness();
     method public static boolean isRunningInUserTestHarness();
@@ -4505,6 +4509,35 @@
     field public String serviceDetails;
   }
 
+  public final class ApplicationExitInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getDefiningUid();
+    method @Nullable public String getDescription();
+    method public int getImportance();
+    method public int getPackageUid();
+    method public int getPid();
+    method @NonNull public String getProcessName();
+    method public int getPss();
+    method public int getRealUid();
+    method public int getReason();
+    method public int getRss();
+    method public int getStatus();
+    method public long getTimestamp();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.ApplicationExitInfo> CREATOR;
+    field public static final int REASON_ANR = 6; // 0x6
+    field public static final int REASON_CRASH = 4; // 0x4
+    field public static final int REASON_CRASH_NATIVE = 5; // 0x5
+    field public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9; // 0x9
+    field public static final int REASON_EXIT_SELF = 1; // 0x1
+    field public static final int REASON_INITIALIZATION_FAILURE = 7; // 0x7
+    field public static final int REASON_LOW_MEMORY = 3; // 0x3
+    field public static final int REASON_OTHER = 10; // 0xa
+    field public static final int REASON_PERMISSION_CHANGE = 8; // 0x8
+    field public static final int REASON_SIGNALED = 2; // 0x2
+    field public static final int REASON_UNKNOWN = 0; // 0x0
+  }
+
   public final class AsyncNotedAppOp implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public String getFeatureId();
@@ -6836,6 +6869,7 @@
     method public boolean isDeviceOwnerApp(String);
     method public boolean isEphemeralUser(@NonNull android.content.ComponentName);
     method public boolean isLockTaskPermitted(String);
+    method public boolean isLockdownAdminConfiguredNetworks(@NonNull android.content.ComponentName);
     method public boolean isLogoutEnabled();
     method public boolean isManagedProfile(@NonNull android.content.ComponentName);
     method public boolean isMasterVolumeMuted(@NonNull android.content.ComponentName);
@@ -6900,6 +6934,7 @@
     method public void setLocationEnabled(@NonNull android.content.ComponentName, boolean);
     method public void setLockTaskFeatures(@NonNull android.content.ComponentName, int);
     method public void setLockTaskPackages(@NonNull android.content.ComponentName, @NonNull String[]) throws java.lang.SecurityException;
+    method public void setLockdownAdminConfiguredNetworks(@NonNull android.content.ComponentName, boolean);
     method public void setLogoutEnabled(@NonNull android.content.ComponentName, boolean);
     method public void setLongSupportMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
     method public void setMasterVolumeMuted(@NonNull android.content.ComponentName, boolean);
@@ -7449,6 +7484,41 @@
 
 }
 
+package android.app.blob {
+
+  public final class BlobHandle implements android.os.Parcelable {
+    method @NonNull public static android.app.blob.BlobHandle createWithSha256(@NonNull byte[], @NonNull CharSequence, long, @NonNull String);
+    method public int describeContents();
+    method public long getExpiryTimeMillis();
+    method @NonNull public CharSequence getLabel();
+    method @NonNull public byte[] getSha256Digest();
+    method @NonNull public String getTag();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.blob.BlobHandle> CREATOR;
+  }
+
+  public class BlobStoreManager {
+    method public void acquireLease(@NonNull android.app.blob.BlobHandle, @IdRes int, long) throws java.io.IOException;
+    method public void acquireLease(@NonNull android.app.blob.BlobHandle, @IdRes int) throws java.io.IOException;
+    method @IntRange(from=1) public long createSession(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+    method @NonNull public android.os.ParcelFileDescriptor openBlob(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+    method @NonNull public android.app.blob.BlobStoreManager.Session openSession(@IntRange(from=1) long) throws java.io.IOException;
+    method public void releaseLease(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+  }
+
+  public static class BlobStoreManager.Session implements java.io.Closeable {
+    method public void abandon() throws java.io.IOException;
+    method public void allowPackageAccess(@NonNull String, @NonNull byte[]) throws java.io.IOException;
+    method public void allowPublicAccess() throws java.io.IOException;
+    method public void allowSameSignatureAccess() throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public void commit(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws java.io.IOException;
+    method public long getSize() throws java.io.IOException;
+    method @NonNull public android.os.ParcelFileDescriptor openWrite(long, long) throws java.io.IOException;
+  }
+
+}
+
 package android.app.job {
 
   public class JobInfo implements android.os.Parcelable {
@@ -11397,6 +11467,7 @@
     method @NonNull public CharSequence getProfileSwitchingLabel(@NonNull android.os.UserHandle);
     method @NonNull public java.util.List<android.os.UserHandle> getTargetUserProfiles();
     method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
+    field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED";
   }
 
   public final class FeatureGroupInfo implements android.os.Parcelable {
@@ -11631,11 +11702,8 @@
     field public static final int STATUS_FAILURE_ABORTED = 3; // 0x3
     field public static final int STATUS_FAILURE_BLOCKED = 2; // 0x2
     field public static final int STATUS_FAILURE_CONFLICT = 5; // 0x5
-    field public static final int STATUS_FAILURE_ILLEGAL_STATE = 9; // 0x9
     field public static final int STATUS_FAILURE_INCOMPATIBLE = 7; // 0x7
     field public static final int STATUS_FAILURE_INVALID = 4; // 0x4
-    field public static final int STATUS_FAILURE_NAME_NOT_FOUND = 8; // 0x8
-    field public static final int STATUS_FAILURE_SECURITY = 10; // 0xa
     field public static final int STATUS_FAILURE_STORAGE = 6; // 0x6
     field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
     field public static final int STATUS_SUCCESS = 0; // 0x0
@@ -11657,7 +11725,6 @@
     method public void removeChildSessionId(int);
     method public void removeSplit(@NonNull String) throws java.io.IOException;
     method public void setStagingProgress(float);
-    method public void transfer(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
     method public void transfer(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
   }
 
@@ -12188,12 +12255,14 @@
     field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
     field public static final int FLAG_STOP_WITH_TASK = 1; // 0x1
     field public static final int FLAG_USE_APP_ZYGOTE = 8; // 0x8
+    field public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
     field public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
     field public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
     field public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
     field public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1; // 0xffffffff
     field public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 2; // 0x2
     field public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 32; // 0x20
+    field public static final int FOREGROUND_SERVICE_TYPE_MICROPHONE = 128; // 0x80
     field public static final int FOREGROUND_SERVICE_TYPE_NONE = 0; // 0x0
     field public static final int FOREGROUND_SERVICE_TYPE_PHONE_CALL = 4; // 0x4
     field public int flags;
@@ -13213,6 +13282,8 @@
     method public static int releaseMemory();
     method public long replace(String, String, android.content.ContentValues);
     method public long replaceOrThrow(String, String, android.content.ContentValues) throws android.database.SQLException;
+    method public void setCustomAggregateFunction(@NonNull String, @NonNull java.util.function.BinaryOperator<java.lang.String>) throws android.database.sqlite.SQLiteException;
+    method public void setCustomScalarFunction(@NonNull String, @NonNull java.util.function.UnaryOperator<java.lang.String>) throws android.database.sqlite.SQLiteException;
     method public void setForeignKeyConstraintsEnabled(boolean);
     method public void setLocale(java.util.Locale);
     method @Deprecated public void setLockingEnabled(boolean);
@@ -16913,7 +16984,9 @@
     ctor public BiometricPrompt.CryptoObject(@NonNull java.security.Signature);
     ctor public BiometricPrompt.CryptoObject(@NonNull javax.crypto.Cipher);
     ctor public BiometricPrompt.CryptoObject(@NonNull javax.crypto.Mac);
+    ctor public BiometricPrompt.CryptoObject(@NonNull android.security.identity.IdentityCredential);
     method public javax.crypto.Cipher getCipher();
+    method @Nullable public android.security.identity.IdentityCredential getIdentityCredential();
     method public javax.crypto.Mac getMac();
     method public java.security.Signature getSignature();
   }
@@ -17874,7 +17947,9 @@
     ctor @Deprecated public FingerprintManager.CryptoObject(@NonNull java.security.Signature);
     ctor @Deprecated public FingerprintManager.CryptoObject(@NonNull javax.crypto.Cipher);
     ctor @Deprecated public FingerprintManager.CryptoObject(@NonNull javax.crypto.Mac);
+    ctor @Deprecated public FingerprintManager.CryptoObject(@NonNull android.security.identity.IdentityCredential);
     method @Deprecated public javax.crypto.Cipher getCipher();
+    method @Deprecated @Nullable public android.security.identity.IdentityCredential getIdentityCredential();
     method @Deprecated public javax.crypto.Mac getMac();
     method @Deprecated public java.security.Signature getSignature();
   }
@@ -18263,6 +18338,7 @@
     field public static final int RIGHT = 7; // 0x7
     field public static final int TOP = 8; // 0x8
     field public static final int TOP_AND_BOTTOM = 9; // 0x9
+    field public static final int TOP_AND_BOTTOM_AND_LEFT = 15; // 0xf
     field public static final int TOP_AND_BOTTOM_AND_RIGHT = 10; // 0xa
     field public static final int TOP_AND_LEFT = 11; // 0xb
     field public static final int TOP_AND_LEFT_AND_RIGHT = 12; // 0xc
@@ -18585,6 +18661,8 @@
     field public static final int CHEROKEE_SUPPLEMENT_ID = 255; // 0xff
     field public static final android.icu.lang.UCharacter.UnicodeBlock CHESS_SYMBOLS;
     field public static final int CHESS_SYMBOLS_ID = 281; // 0x119
+    field public static final android.icu.lang.UCharacter.UnicodeBlock CHORASMIAN;
+    field public static final int CHORASMIAN_ID = 301; // 0x12d
     field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY;
     field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY_FORMS;
     field public static final int CJK_COMPATIBILITY_FORMS_ID = 83; // 0x53
@@ -18612,6 +18690,8 @@
     field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E_ID = 256; // 0x100
     field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F;
     field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F_ID = 274; // 0x112
+    field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G;
+    field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G_ID = 302; // 0x12e
     field public static final int CJK_UNIFIED_IDEOGRAPHS_ID = 71; // 0x47
     field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
     field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS_EXTENDED;
@@ -18661,6 +18741,8 @@
     field public static final int DEVANAGARI_ID = 15; // 0xf
     field public static final android.icu.lang.UCharacter.UnicodeBlock DINGBATS;
     field public static final int DINGBATS_ID = 56; // 0x38
+    field public static final android.icu.lang.UCharacter.UnicodeBlock DIVES_AKURU;
+    field public static final int DIVES_AKURU_ID = 303; // 0x12f
     field public static final android.icu.lang.UCharacter.UnicodeBlock DOGRA;
     field public static final int DOGRA_ID = 282; // 0x11a
     field public static final android.icu.lang.UCharacter.UnicodeBlock DOMINO_TILES;
@@ -18789,6 +18871,8 @@
     field public static final int KAYAH_LI_ID = 162; // 0xa2
     field public static final android.icu.lang.UCharacter.UnicodeBlock KHAROSHTHI;
     field public static final int KHAROSHTHI_ID = 137; // 0x89
+    field public static final android.icu.lang.UCharacter.UnicodeBlock KHITAN_SMALL_SCRIPT;
+    field public static final int KHITAN_SMALL_SCRIPT_ID = 304; // 0x130
     field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER;
     field public static final int KHMER_ID = 36; // 0x24
     field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER_SYMBOLS;
@@ -18827,6 +18911,8 @@
     field public static final int LINEAR_B_SYLLABARY_ID = 117; // 0x75
     field public static final android.icu.lang.UCharacter.UnicodeBlock LISU;
     field public static final int LISU_ID = 176; // 0xb0
+    field public static final android.icu.lang.UCharacter.UnicodeBlock LISU_SUPPLEMENT;
+    field public static final int LISU_SUPPLEMENT_ID = 305; // 0x131
     field public static final android.icu.lang.UCharacter.UnicodeBlock LOW_SURROGATES;
     field public static final int LOW_SURROGATES_ID = 77; // 0x4d
     field public static final android.icu.lang.UCharacter.UnicodeBlock LYCIAN;
@@ -19038,6 +19124,8 @@
     field public static final int SYLOTI_NAGRI_ID = 143; // 0x8f
     field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A;
     field public static final int SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A_ID = 298; // 0x12a
+    field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_FOR_LEGACY_COMPUTING;
+    field public static final int SYMBOLS_FOR_LEGACY_COMPUTING_ID = 306; // 0x132
     field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC;
     field public static final int SYRIAC_ID = 13; // 0xd
     field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC_SUPPLEMENT;
@@ -19066,6 +19154,8 @@
     field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_COMPONENTS;
     field public static final int TANGUT_COMPONENTS_ID = 273; // 0x111
     field public static final int TANGUT_ID = 272; // 0x110
+    field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_SUPPLEMENT;
+    field public static final int TANGUT_SUPPLEMENT_ID = 307; // 0x133
     field public static final android.icu.lang.UCharacter.UnicodeBlock TELUGU;
     field public static final int TELUGU_ID = 21; // 0x15
     field public static final android.icu.lang.UCharacter.UnicodeBlock THAANA;
@@ -19100,6 +19190,8 @@
     field public static final int WANCHO_ID = 300; // 0x12c
     field public static final android.icu.lang.UCharacter.UnicodeBlock WARANG_CITI;
     field public static final int WARANG_CITI_ID = 252; // 0xfc
+    field public static final android.icu.lang.UCharacter.UnicodeBlock YEZIDI;
+    field public static final int YEZIDI_ID = 308; // 0x134
     field public static final android.icu.lang.UCharacter.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
     field public static final int YIJING_HEXAGRAM_SYMBOLS_ID = 116; // 0x74
     field public static final android.icu.lang.UCharacter.UnicodeBlock YI_RADICALS;
@@ -19396,6 +19488,7 @@
     field public static final int CHAKMA = 118; // 0x76
     field public static final int CHAM = 66; // 0x42
     field public static final int CHEROKEE = 6; // 0x6
+    field public static final int CHORASMIAN = 189; // 0xbd
     field public static final int CIRTH = 67; // 0x43
     field public static final int COMMON = 0; // 0x0
     field public static final int COPTIC = 7; // 0x7
@@ -19405,6 +19498,7 @@
     field public static final int DEMOTIC_EGYPTIAN = 69; // 0x45
     field public static final int DESERET = 9; // 0x9
     field public static final int DEVANAGARI = 10; // 0xa
+    field public static final int DIVES_AKURU = 190; // 0xbe
     field public static final int DOGRA = 178; // 0xb2
     field public static final int DUPLOYAN = 135; // 0x87
     field public static final int EASTERN_SYRIAC = 97; // 0x61
@@ -19446,6 +19540,7 @@
     field public static final int KATAKANA_OR_HIRAGANA = 54; // 0x36
     field public static final int KAYAH_LI = 79; // 0x4f
     field public static final int KHAROSHTHI = 57; // 0x39
+    field public static final int KHITAN_SMALL_SCRIPT = 191; // 0xbf
     field public static final int KHMER = 23; // 0x17
     field public static final int KHOJKI = 157; // 0x9d
     field public static final int KHUDAWADI = 145; // 0x91
@@ -19563,6 +19658,7 @@
     field public static final int WARANG_CITI = 146; // 0x92
     field public static final int WESTERN_SYRIAC = 96; // 0x60
     field public static final int WOLEAI = 155; // 0x9b
+    field public static final int YEZIDI = 192; // 0xc0
     field public static final int YI = 41; // 0x29
     field public static final int ZANABAZAR_SQUARE = 177; // 0xb1
   }
@@ -22818,6 +22914,7 @@
     field public static final android.icu.util.VersionInfo UNICODE_11_0;
     field public static final android.icu.util.VersionInfo UNICODE_12_0;
     field public static final android.icu.util.VersionInfo UNICODE_12_1;
+    field public static final android.icu.util.VersionInfo UNICODE_13_0;
     field public static final android.icu.util.VersionInfo UNICODE_1_0;
     field public static final android.icu.util.VersionInfo UNICODE_1_0_1;
     field public static final android.icu.util.VersionInfo UNICODE_1_1_0;
@@ -24262,6 +24359,9 @@
     method public int write(@NonNull float[], int, int, int);
     method public int write(@NonNull java.nio.ByteBuffer, int, int);
     method public int write(@NonNull java.nio.ByteBuffer, int, int, long);
+    field public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1; // 0x1
+    field public static final int ENCAPSULATION_MODE_HANDLE = 2; // 0x2
+    field public static final int ENCAPSULATION_MODE_NONE = 0; // 0x0
     field public static final int ERROR = -1; // 0xffffffff
     field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe
     field public static final int ERROR_DEAD_OBJECT = -6; // 0xfffffffa
@@ -24288,10 +24388,12 @@
     method @NonNull public android.media.AudioTrack.Builder setAudioAttributes(@NonNull android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
     method @NonNull public android.media.AudioTrack.Builder setAudioFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException;
     method @NonNull public android.media.AudioTrack.Builder setBufferSizeInBytes(@IntRange(from=0) int) throws java.lang.IllegalArgumentException;
+    method @NonNull public android.media.AudioTrack.Builder setEncapsulationMode(int);
     method @NonNull public android.media.AudioTrack.Builder setOffloadedPlayback(boolean);
     method @NonNull public android.media.AudioTrack.Builder setPerformanceMode(int);
     method @NonNull public android.media.AudioTrack.Builder setSessionId(@IntRange(from=1) int) throws java.lang.IllegalArgumentException;
     method @NonNull public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException;
+    method @NonNull public android.media.AudioTrack.Builder setTunerConfiguration(@NonNull android.media.AudioTrack.TunerConfiguration);
   }
 
   public static final class AudioTrack.MetricsConstants {
@@ -24319,6 +24421,18 @@
     method public void onTearDown(@NonNull android.media.AudioTrack);
   }
 
+  public static class AudioTrack.TunerConfiguration {
+    method public int getContentId();
+    method public int getSyncId();
+  }
+
+  public static class AudioTrack.TunerConfiguration.Builder {
+    ctor public AudioTrack.TunerConfiguration.Builder();
+    method @NonNull public android.media.AudioTrack.TunerConfiguration build();
+    method @NonNull public android.media.AudioTrack.TunerConfiguration.Builder setContentId(@IntRange(from=1) int);
+    method @NonNull public android.media.AudioTrack.TunerConfiguration.Builder setSyncId(@IntRange(from=1) int);
+  }
+
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
@@ -24326,28 +24440,39 @@
     method public static boolean hasProfile(int, int);
     field public static final int QUALITY_1080P = 6; // 0x6
     field public static final int QUALITY_2160P = 8; // 0x8
+    field public static final int QUALITY_2K = 12; // 0xc
     field public static final int QUALITY_480P = 4; // 0x4
+    field public static final int QUALITY_4KDCI = 10; // 0xa
     field public static final int QUALITY_720P = 5; // 0x5
     field public static final int QUALITY_CIF = 3; // 0x3
     field public static final int QUALITY_HIGH = 1; // 0x1
     field public static final int QUALITY_HIGH_SPEED_1080P = 2004; // 0x7d4
     field public static final int QUALITY_HIGH_SPEED_2160P = 2005; // 0x7d5
     field public static final int QUALITY_HIGH_SPEED_480P = 2002; // 0x7d2
+    field public static final int QUALITY_HIGH_SPEED_4KDCI = 2008; // 0x7d8
     field public static final int QUALITY_HIGH_SPEED_720P = 2003; // 0x7d3
+    field public static final int QUALITY_HIGH_SPEED_CIF = 2006; // 0x7d6
     field public static final int QUALITY_HIGH_SPEED_HIGH = 2001; // 0x7d1
     field public static final int QUALITY_HIGH_SPEED_LOW = 2000; // 0x7d0
+    field public static final int QUALITY_HIGH_SPEED_VGA = 2007; // 0x7d7
     field public static final int QUALITY_LOW = 0; // 0x0
     field public static final int QUALITY_QCIF = 2; // 0x2
+    field public static final int QUALITY_QHD = 11; // 0xb
     field public static final int QUALITY_QVGA = 7; // 0x7
     field public static final int QUALITY_TIME_LAPSE_1080P = 1006; // 0x3ee
     field public static final int QUALITY_TIME_LAPSE_2160P = 1008; // 0x3f0
+    field public static final int QUALITY_TIME_LAPSE_2K = 1012; // 0x3f4
     field public static final int QUALITY_TIME_LAPSE_480P = 1004; // 0x3ec
+    field public static final int QUALITY_TIME_LAPSE_4KDCI = 1010; // 0x3f2
     field public static final int QUALITY_TIME_LAPSE_720P = 1005; // 0x3ed
     field public static final int QUALITY_TIME_LAPSE_CIF = 1003; // 0x3eb
     field public static final int QUALITY_TIME_LAPSE_HIGH = 1001; // 0x3e9
     field public static final int QUALITY_TIME_LAPSE_LOW = 1000; // 0x3e8
     field public static final int QUALITY_TIME_LAPSE_QCIF = 1002; // 0x3ea
+    field public static final int QUALITY_TIME_LAPSE_QHD = 1011; // 0x3f3
     field public static final int QUALITY_TIME_LAPSE_QVGA = 1007; // 0x3ef
+    field public static final int QUALITY_TIME_LAPSE_VGA = 1009; // 0x3f1
+    field public static final int QUALITY_VGA = 9; // 0x9
     field public int audioBitRate;
     field public int audioChannels;
     field public int audioCodec;
@@ -24676,11 +24801,13 @@
 
   public final class MediaCas implements java.lang.AutoCloseable {
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
+    ctor public MediaCas(int, @Nullable String, int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
     method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
     method protected void finalize();
     method public static boolean isSystemIdSupported(int);
     method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
+    method @Nullable public android.media.MediaCas.Session openSession(int, int) throws android.media.MediaCasException;
     method public void processEmm(@NonNull byte[], int, int) throws android.media.MediaCasException;
     method public void processEmm(@NonNull byte[]) throws android.media.MediaCasException;
     method public void provision(@NonNull String) throws android.media.MediaCasException;
@@ -24688,10 +24815,32 @@
     method public void sendEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException;
     method public void setEventListener(@Nullable android.media.MediaCas.EventListener, @Nullable android.os.Handler);
     method public void setPrivateData(@NonNull byte[]) throws android.media.MediaCasException;
+    field public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = 0; // 0x0
+    field public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = 1; // 0x1
+    field public static final int SCRAMBLING_MODE_AES128 = 9; // 0x9
+    field public static final int SCRAMBLING_MODE_AES_ECB = 10; // 0xa
+    field public static final int SCRAMBLING_MODE_AES_SCTE52 = 11; // 0xb
+    field public static final int SCRAMBLING_MODE_DVB_CISSA_V1 = 6; // 0x6
+    field public static final int SCRAMBLING_MODE_DVB_CSA1 = 1; // 0x1
+    field public static final int SCRAMBLING_MODE_DVB_CSA2 = 2; // 0x2
+    field public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE = 5; // 0x5
+    field public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL = 4; // 0x4
+    field public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD = 3; // 0x3
+    field public static final int SCRAMBLING_MODE_DVB_IDSA = 7; // 0x7
+    field public static final int SCRAMBLING_MODE_MULTI2 = 8; // 0x8
+    field public static final int SCRAMBLING_MODE_RESERVED = 0; // 0x0
+    field public static final int SCRAMBLING_MODE_TDES_ECB = 12; // 0xc
+    field public static final int SCRAMBLING_MODE_TDES_SCTE52 = 13; // 0xd
+    field public static final int SESSION_USAGE_LIVE = 0; // 0x0
+    field public static final int SESSION_USAGE_PLAYBACK = 1; // 0x1
+    field public static final int SESSION_USAGE_RECORD = 2; // 0x2
+    field public static final int SESSION_USAGE_TIMESHIFT = 3; // 0x3
   }
 
   public static interface MediaCas.EventListener {
     method public void onEvent(@NonNull android.media.MediaCas, int, int, @Nullable byte[]);
+    method public default void onPluginStatusUpdate(@NonNull android.media.MediaCas, int, int);
+    method public default void onResourceLost(@NonNull android.media.MediaCas);
     method public default void onSessionEvent(@NonNull android.media.MediaCas, @NonNull android.media.MediaCas.Session, int, int, @Nullable byte[]);
   }
 
@@ -24702,6 +24851,7 @@
 
   public final class MediaCas.Session implements java.lang.AutoCloseable {
     method public void close();
+    method @NonNull public byte[] getSessionId();
     method public void processEcm(@NonNull byte[], int, int) throws android.media.MediaCasException;
     method public void processEcm(@NonNull byte[]) throws android.media.MediaCasException;
     method public void sendSessionEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException;
@@ -24714,6 +24864,9 @@
   public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException {
   }
 
+  public static final class MediaCasException.InsufficientResourceException extends android.media.MediaCasException {
+  }
+
   public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException {
   }
 
@@ -25630,10 +25783,12 @@
     field public static final int COLOR_TRANSFER_LINEAR = 1; // 0x1
     field public static final int COLOR_TRANSFER_SDR_VIDEO = 3; // 0x3
     field public static final int COLOR_TRANSFER_ST2084 = 6; // 0x6
+    field public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode";
     field public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
     field public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
     field public static final String KEY_AAC_DRC_EFFECT_TYPE = "aac-drc-effect-type";
     field public static final String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
+    field public static final String KEY_AAC_DRC_OUTPUT_LOUDNESS = "aac-drc-output-loudness";
     field public static final String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
     field public static final String KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
     field public static final String KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
@@ -26332,6 +26487,7 @@
 
   public final class MediaRoute2Info implements android.os.Parcelable {
     method public int describeContents();
+    method @Nullable public String getClientPackageName();
     method public int getConnectionState();
     method @Nullable public CharSequence getDescription();
     method public int getDeviceType();
@@ -26353,6 +26509,9 @@
     field public static final int DEVICE_TYPE_REMOTE_SPEAKER = 2; // 0x2
     field public static final int DEVICE_TYPE_REMOTE_TV = 1; // 0x1
     field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final String FEATURE_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+    field public static final String FEATURE_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+    field public static final String FEATURE_REMOTE_PLAYBACK = "android.media.intent.category.REMOTE_PLAYBACK";
     field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
     field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
   }
@@ -26377,9 +26536,23 @@
 
   public abstract class MediaRoute2ProviderService extends android.app.Service {
     ctor public MediaRoute2ProviderService();
+    method @NonNull public final java.util.List<android.media.RoutingSessionInfo> getAllSessionInfo();
+    method @Nullable public final android.media.RoutingSessionInfo getSessionInfo(@NonNull String);
     method public final void notifyRoutes(@NonNull java.util.Collection<android.media.MediaRoute2Info>);
-    method @NonNull public android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public final void notifySessionCreated(@NonNull android.media.RoutingSessionInfo, long);
+    method public final void notifySessionCreationFailed(long);
+    method public final void notifySessionReleased(@NonNull String);
+    method public final void notifySessionUpdated(@NonNull android.media.RoutingSessionInfo);
+    method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onCreateSession(@NonNull String, @NonNull String, long, @Nullable android.os.Bundle);
+    method public abstract void onDeselectRoute(@NonNull String, @NonNull String);
     method public void onDiscoveryPreferenceChanged(@NonNull android.media.RouteDiscoveryPreference);
+    method public abstract void onReleaseSession(@NonNull String);
+    method public abstract void onSelectRoute(@NonNull String, @NonNull String);
+    method public abstract void onSetVolume(@NonNull String, int);
+    method public abstract void onTransferToRoute(@NonNull String, @NonNull String);
+    method public abstract void onUpdateVolume(@NonNull String, int);
+    field public static final long REQUEST_ID_UNKNOWN = 0L; // 0x0L
     field public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
   }
 
@@ -26507,12 +26680,22 @@
   }
 
   public class MediaRouter2 {
+    method @NonNull public java.util.List<android.media.MediaRouter2.RoutingController> getControllers();
     method @NonNull public static android.media.MediaRouter2 getInstance(@NonNull android.content.Context);
     method @NonNull public java.util.List<android.media.MediaRoute2Info> getRoutes();
+    method @NonNull public android.media.MediaRouter2.RoutingController getSystemController();
+    method public void registerControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.RoutingControllerCallback);
     method public void registerRouteCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.RouteCallback, @NonNull android.media.RouteDiscoveryPreference);
+    method public void requestCreateController(@NonNull android.media.MediaRoute2Info);
+    method public void setOnGetControllerHintsListener(@Nullable android.media.MediaRouter2.OnGetControllerHintsListener);
+    method public void unregisterControllerCallback(@NonNull android.media.MediaRouter2.RoutingControllerCallback);
     method public void unregisterRouteCallback(@NonNull android.media.MediaRouter2.RouteCallback);
   }
 
+  public static interface MediaRouter2.OnGetControllerHintsListener {
+    method @Nullable public android.os.Bundle onGetControllerHints(@NonNull android.media.MediaRoute2Info);
+  }
+
   public static class MediaRouter2.RouteCallback {
     ctor public MediaRouter2.RouteCallback();
     method public void onRoutesAdded(@NonNull java.util.List<android.media.MediaRoute2Info>);
@@ -26520,6 +26703,28 @@
     method public void onRoutesRemoved(@NonNull java.util.List<android.media.MediaRoute2Info>);
   }
 
+  public class MediaRouter2.RoutingController {
+    method public void deselectRoute(@NonNull android.media.MediaRoute2Info);
+    method @Nullable public android.os.Bundle getControlHints();
+    method @NonNull public java.util.List<android.media.MediaRoute2Info> getDeselectableRoutes();
+    method @NonNull public String getId();
+    method @NonNull public java.util.List<android.media.MediaRoute2Info> getSelectableRoutes();
+    method @NonNull public java.util.List<android.media.MediaRoute2Info> getSelectedRoutes();
+    method @NonNull public java.util.List<android.media.MediaRoute2Info> getTransferrableRoutes();
+    method public boolean isReleased();
+    method public void release();
+    method public void selectRoute(@NonNull android.media.MediaRoute2Info);
+    method public void transferToRoute(@NonNull android.media.MediaRoute2Info);
+  }
+
+  public static class MediaRouter2.RoutingControllerCallback {
+    ctor public MediaRouter2.RoutingControllerCallback();
+    method public void onControllerCreated(@NonNull android.media.MediaRouter2.RoutingController);
+    method public void onControllerCreationFailed(@NonNull android.media.MediaRoute2Info);
+    method public void onControllerReleased(@NonNull android.media.MediaRouter2.RoutingController);
+    method public void onControllerUpdated(@NonNull android.media.MediaRouter2.RoutingController);
+  }
+
   public class MediaScannerConnection implements android.content.ServiceConnection {
     ctor public MediaScannerConnection(android.content.Context, android.media.MediaScannerConnection.MediaScannerConnectionClient);
     method public void connect();
@@ -26894,6 +27099,38 @@
     method @NonNull public android.media.RouteDiscoveryPreference.Builder setPreferredFeatures(@NonNull java.util.List<java.lang.String>);
   }
 
+  public final class RoutingSessionInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getClientPackageName();
+    method @Nullable public android.os.Bundle getControlHints();
+    method @NonNull public java.util.List<java.lang.String> getDeselectableRoutes();
+    method @NonNull public String getId();
+    method @NonNull public java.util.List<java.lang.String> getSelectableRoutes();
+    method @NonNull public java.util.List<java.lang.String> getSelectedRoutes();
+    method @NonNull public java.util.List<java.lang.String> getTransferrableRoutes();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.RoutingSessionInfo> CREATOR;
+  }
+
+  public static final class RoutingSessionInfo.Builder {
+    ctor public RoutingSessionInfo.Builder(@NonNull String, @NonNull String);
+    ctor public RoutingSessionInfo.Builder(@NonNull android.media.RoutingSessionInfo);
+    method @NonNull public android.media.RoutingSessionInfo.Builder addDeselectableRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder addSelectableRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder addSelectedRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder addTransferrableRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo build();
+    method @NonNull public android.media.RoutingSessionInfo.Builder clearDeselectableRoutes();
+    method @NonNull public android.media.RoutingSessionInfo.Builder clearSelectableRoutes();
+    method @NonNull public android.media.RoutingSessionInfo.Builder clearSelectedRoutes();
+    method @NonNull public android.media.RoutingSessionInfo.Builder clearTransferrableRoutes();
+    method @NonNull public android.media.RoutingSessionInfo.Builder removeDeselectableRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder removeSelectableRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder removeSelectedRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder removeTransferrableRoute(@NonNull String);
+    method @NonNull public android.media.RoutingSessionInfo.Builder setControlHints(@Nullable android.os.Bundle);
+  }
+
   public final class Session2Command implements android.os.Parcelable {
     ctor public Session2Command(int);
     ctor public Session2Command(@NonNull String, @Nullable android.os.Bundle);
@@ -28700,6 +28937,19 @@
     field public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1; // 0x1
     field public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 4; // 0x4
     field public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; // 0x3
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT = 16; // 0x10
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID = 15; // 0xf
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE = 14; // 0xe
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 7; // 0x7
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED = 10; // 0xa
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION = 11; // 0xb
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING = 12; // 0xc
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD = 13; // 0xd
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED = 8; // 0x8
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING = 17; // 0x11
+    field public static final int VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN = 18; // 0x12
+    field public static final int VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 6; // 0x6
+    field public static final int VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 5; // 0x5
     field public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; // 0x1
     field public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = 0; // 0x0
     field public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; // 0x2
@@ -28721,6 +28971,11 @@
     method @Nullable public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(@NonNull String, @NonNull String);
     method @Nullable public abstract android.media.tv.TvInputService.Session onCreateSession(String);
     method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String);
+    field public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100; // 0x64
+    field public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400; // 0x190
+    field public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300; // 0x12c
+    field public static final int PRIORITY_HINT_USE_CASE_TYPE_RECORD = 500; // 0x1f4
+    field public static final int PRIORITY_HINT_USE_CASE_TYPE_SCAN = 200; // 0xc8
     field public static final String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -30183,6 +30438,7 @@
     method public void close();
     method public void continueCall(int) throws android.net.sip.SipException;
     method public void endCall() throws android.net.sip.SipException;
+    method @Nullable public android.net.rtp.AudioGroup getAudioGroup();
     method public android.net.sip.SipProfile getLocalProfile();
     method public android.net.sip.SipProfile getPeerProfile();
     method public int getState();
@@ -30193,6 +30449,7 @@
     method public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
     method public void sendDtmf(int);
     method public void sendDtmf(int, android.os.Message);
+    method public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
     method public void setListener(android.net.sip.SipAudioCall.Listener);
     method public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
     method public void setSpeakerMode(boolean);
@@ -30241,6 +30498,7 @@
     method public void close(String) throws android.net.sip.SipException;
     method public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
     method public static String getCallId(android.content.Intent);
+    method @NonNull public java.util.List<android.net.sip.SipProfile> getListOfProfiles() throws android.net.sip.SipException;
     method public static String getOfferSessionDescription(android.content.Intent);
     method public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
     method public static boolean isApiSupported(android.content.Context);
@@ -30258,6 +30516,11 @@
     method public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
     method public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
     method public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+    field public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
+    field public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
+    field public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
+    field public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
+    field public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
     field public static final String EXTRA_CALL_ID = "android:sipCallID";
     field public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
     field public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
@@ -30267,6 +30530,7 @@
     method public int describeContents();
     method public String getAuthUserName();
     method public boolean getAutoRegistration();
+    method public int getCallingUid();
     method public String getDisplayName();
     method public String getPassword();
     method public int getPort();
@@ -30277,6 +30541,7 @@
     method public String getSipDomain();
     method public String getUriString();
     method public String getUserName();
+    method public void setCallingUid(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
   }
@@ -30384,7 +30649,9 @@
   }
 
   public class ScanResult implements android.os.Parcelable {
+    ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
     method public int describeContents();
+    method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
     method public int getWifiStandard();
     method public boolean is80211mcResponder();
     method public boolean isPasspointNetwork();
@@ -30395,6 +30662,7 @@
     field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
     field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
     field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
     field public String SSID;
     field public static final int WIFI_STANDARD_11AC = 5; // 0x5
     field public static final int WIFI_STANDARD_11AX = 6; // 0x6
@@ -30412,6 +30680,28 @@
     field public CharSequence venueName;
   }
 
+  public static class ScanResult.InformationElement {
+    ctor public ScanResult.InformationElement(@NonNull android.net.wifi.ScanResult.InformationElement);
+    method @NonNull public java.nio.ByteBuffer getBytes();
+    method public int getId();
+    method public int getIdExt();
+  }
+
+  public final class SoftApConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.net.MacAddress getBssid();
+    method @Nullable public String getPassphrase();
+    method public int getSecurityType();
+    method @Nullable public String getSsid();
+    method public boolean isHiddenSsid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
+    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
+    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
+    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
+    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
+  }
+
   public enum SupplicantState implements android.os.Parcelable {
     method public int describeContents();
     method public static boolean isValidState(android.net.wifi.SupplicantState);
@@ -30609,6 +30899,8 @@
     method public int getIpAddress();
     method public int getLinkSpeed();
     method public String getMacAddress();
+    method public int getMaxSupportedRxLinkSpeedMbps();
+    method public int getMaxSupportedTxLinkSpeedMbps();
     method public int getNetworkId();
     method @Nullable public String getPasspointFqdn();
     method @Nullable public String getPasspointProviderFriendlyName();
@@ -30661,6 +30953,7 @@
     method public boolean isTdlsSupported();
     method public boolean isWapiSupported();
     method public boolean isWifiEnabled();
+    method public boolean isWifiStandardSupported(int);
     method public boolean isWpa3SaeSupported();
     method public boolean isWpa3SuiteBSupported();
     method @Deprecated public boolean pingSupplicant();
@@ -30703,6 +30996,7 @@
     field public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; // 0x3
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; // 0x4
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; // 0x6
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; // 0x2
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
     field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
@@ -30744,7 +31038,8 @@
 
   public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
     method public void close();
-    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
+    method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
+    method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
   }
 
   public class WifiManager.MulticastLock {
@@ -30819,6 +31114,7 @@
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
@@ -31314,8 +31610,10 @@
     method public int getControlPort();
     method public int getDeviceType();
     method public int getMaxThroughput();
+    method public boolean isContentProtectionSupported();
     method public boolean isSessionAvailable();
     method public boolean isWfdEnabled();
+    method public void setContentProtectionSupported(boolean);
     method public void setControlPort(int);
     method public boolean setDeviceType(int);
     method public void setMaxThroughput(int);
@@ -36210,10 +36508,10 @@
     method public static android.content.Intent createUserCreationIntent(@Nullable String, @Nullable String, @Nullable String, @Nullable android.os.PersistableBundle);
     method @WorkerThread public android.os.Bundle getApplicationRestrictions(String);
     method public long getSerialNumberForUser(android.os.UserHandle);
-    method public int getUserCount();
+    method @RequiresPermission("android.permission.MANAGE_USERS") public int getUserCount();
     method public long getUserCreationTime(android.os.UserHandle);
     method public android.os.UserHandle getUserForSerialNumber(long);
-    method public String getUserName();
+    method @NonNull @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}, conditional=true) public String getUserName();
     method public java.util.List<android.os.UserHandle> getUserProfiles();
     method public android.os.Bundle getUserRestrictions();
     method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public android.os.Bundle getUserRestrictions(android.os.UserHandle);
@@ -36223,13 +36521,14 @@
     method public boolean isQuietModeEnabled(android.os.UserHandle);
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
-    method public boolean isUserRunning(android.os.UserHandle);
-    method public boolean isUserRunningOrStopping(android.os.UserHandle);
+    method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public boolean isUserRunning(android.os.UserHandle);
+    method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public boolean isUserRunningOrStopping(android.os.UserHandle);
     method public boolean isUserUnlocked();
-    method public boolean isUserUnlocked(android.os.UserHandle);
-    method public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle);
+    method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public boolean isUserUnlocked(android.os.UserHandle);
+    method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.MODIFY_QUIET_MODE"}, conditional=true) public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle);
+    method public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle, int);
     method @Deprecated public boolean setRestrictionsChallenge(String);
-    method @Deprecated public void setUserRestriction(String, boolean);
+    method @Deprecated @RequiresPermission("android.permission.MANAGE_USERS") public void setUserRestriction(String, boolean);
     method @Deprecated public void setUserRestrictions(android.os.Bundle);
     method @Deprecated public void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
     method public static boolean supportsMultipleUsers();
@@ -36289,6 +36588,7 @@
     field public static final String DISALLOW_USER_SWITCH = "no_user_switch";
     field public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps";
     field public static final String KEY_RESTRICTIONS_PENDING = "restrictions_pending";
+    field public static final int QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED = 1; // 0x1
     field public static final int USER_CREATION_FAILED_NOT_PERMITTED = 1; // 0x1
     field public static final int USER_CREATION_FAILED_NO_MORE_USERS = 2; // 0x2
     field public static final int USER_OPERATION_ERROR_CURRENT_USER = 4; // 0x4
@@ -39466,6 +39766,7 @@
   public static interface MediaStore.Files.FileColumns extends android.provider.MediaStore.MediaColumns {
     field public static final String MEDIA_TYPE = "media_type";
     field public static final int MEDIA_TYPE_AUDIO = 2; // 0x2
+    field public static final int MEDIA_TYPE_DOCUMENT = 6; // 0x6
     field public static final int MEDIA_TYPE_IMAGE = 1; // 0x1
     field public static final int MEDIA_TYPE_NONE = 0; // 0x0
     field public static final int MEDIA_TYPE_PLAYLIST = 4; // 0x4
@@ -41622,6 +41923,7 @@
   public final class SEService {
     ctor public SEService(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, @NonNull android.se.omapi.SEService.OnConnectedListener);
     method @NonNull public android.se.omapi.Reader[] getReaders();
+    method @NonNull public android.se.omapi.Reader getUiccReader(int);
     method @NonNull public String getVersion();
     method public boolean isConnected();
     method public void shutdown();
@@ -41766,6 +42068,139 @@
 
 }
 
+package android.security.identity {
+
+  public class AccessControlProfile {
+  }
+
+  public static final class AccessControlProfile.Builder {
+    ctor public AccessControlProfile.Builder(@NonNull android.security.identity.AccessControlProfileId);
+    method @NonNull public android.security.identity.AccessControlProfile build();
+    method @NonNull public android.security.identity.AccessControlProfile.Builder setReaderCertificate(@NonNull java.security.cert.X509Certificate);
+    method @NonNull public android.security.identity.AccessControlProfile.Builder setUserAuthenticationRequired(boolean);
+    method @NonNull public android.security.identity.AccessControlProfile.Builder setUserAuthenticationTimeout(long);
+  }
+
+  public class AccessControlProfileId {
+    ctor public AccessControlProfileId(int);
+    method public int getId();
+  }
+
+  public class AlreadyPersonalizedException extends android.security.identity.IdentityCredentialException {
+    ctor public AlreadyPersonalizedException(@NonNull String);
+    ctor public AlreadyPersonalizedException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class CipherSuiteNotSupportedException extends android.security.identity.IdentityCredentialException {
+    ctor public CipherSuiteNotSupportedException(@NonNull String);
+    ctor public CipherSuiteNotSupportedException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class DocTypeNotSupportedException extends android.security.identity.IdentityCredentialException {
+    ctor public DocTypeNotSupportedException(@NonNull String);
+    ctor public DocTypeNotSupportedException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class EphemeralPublicKeyNotFoundException extends android.security.identity.IdentityCredentialException {
+    ctor public EphemeralPublicKeyNotFoundException(@NonNull String);
+    ctor public EphemeralPublicKeyNotFoundException(@NonNull String, @NonNull Throwable);
+  }
+
+  public abstract class IdentityCredential {
+    method @NonNull public abstract java.security.KeyPair createEphemeralKeyPair();
+    method @NonNull public abstract byte[] decryptMessageFromReader(@NonNull byte[]) throws android.security.identity.MessageDecryptionException;
+    method @NonNull public abstract byte[] encryptMessageToReader(@NonNull byte[]);
+    method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getAuthKeysNeedingCertification();
+    method @NonNull public abstract int[] getAuthenticationDataUsageCount();
+    method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain();
+    method @NonNull public abstract android.security.identity.ResultData getEntries(@Nullable byte[], @NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>, @Nullable byte[], @Nullable byte[]) throws android.security.identity.EphemeralPublicKeyNotFoundException, android.security.identity.InvalidReaderSignatureException, android.security.identity.InvalidRequestMessageException, android.security.identity.NoAuthenticationKeyAvailableException, android.security.identity.SessionTranscriptMismatchException;
+    method public abstract void setAllowUsingExhaustedKeys(boolean);
+    method public abstract void setAvailableAuthenticationKeys(int, int);
+    method public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey) throws java.security.InvalidKeyException;
+    method public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
+  }
+
+  public class IdentityCredentialException extends java.lang.Exception {
+    ctor public IdentityCredentialException(@NonNull String);
+    ctor public IdentityCredentialException(@NonNull String, @NonNull Throwable);
+  }
+
+  public abstract class IdentityCredentialStore {
+    method @NonNull public abstract android.security.identity.WritableIdentityCredential createCredential(@NonNull String, @NonNull String) throws android.security.identity.AlreadyPersonalizedException, android.security.identity.DocTypeNotSupportedException;
+    method @Nullable public abstract byte[] deleteCredentialByName(@NonNull String);
+    method @Nullable public abstract android.security.identity.IdentityCredential getCredentialByName(@NonNull String, int) throws android.security.identity.CipherSuiteNotSupportedException;
+    method @Nullable public static android.security.identity.IdentityCredentialStore getDirectAccessInstance(@NonNull android.content.Context);
+    method @Nullable public static android.security.identity.IdentityCredentialStore getInstance(@NonNull android.content.Context);
+    method @NonNull public abstract String[] getSupportedDocTypes();
+    field public static final int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1; // 0x1
+  }
+
+  public class InvalidReaderSignatureException extends android.security.identity.IdentityCredentialException {
+    ctor public InvalidReaderSignatureException(@NonNull String);
+    ctor public InvalidReaderSignatureException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class InvalidRequestMessageException extends android.security.identity.IdentityCredentialException {
+    ctor public InvalidRequestMessageException(@NonNull String);
+    ctor public InvalidRequestMessageException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class MessageDecryptionException extends android.security.identity.IdentityCredentialException {
+    ctor public MessageDecryptionException(@NonNull String);
+    ctor public MessageDecryptionException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class NoAuthenticationKeyAvailableException extends android.security.identity.IdentityCredentialException {
+    ctor public NoAuthenticationKeyAvailableException(@NonNull String);
+    ctor public NoAuthenticationKeyAvailableException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class PersonalizationData {
+  }
+
+  public static final class PersonalizationData.Builder {
+    ctor public PersonalizationData.Builder();
+    method @NonNull public android.security.identity.PersonalizationData.Builder addAccessControlProfile(@NonNull android.security.identity.AccessControlProfile);
+    method @NonNull public android.security.identity.PersonalizationData build();
+    method @NonNull public android.security.identity.PersonalizationData.Builder setEntry(@NonNull String, @NonNull String, @NonNull java.util.Collection<android.security.identity.AccessControlProfileId>, @NonNull byte[]);
+  }
+
+  public abstract class ResultData {
+    method @NonNull public abstract byte[] getAuthenticatedData();
+    method @Nullable public abstract byte[] getEntry(@NonNull String, @NonNull String);
+    method @Nullable public abstract java.util.Collection<java.lang.String> getEntryNames(@NonNull String);
+    method @Nullable public abstract byte[] getMessageAuthenticationCode();
+    method @NonNull public abstract java.util.Collection<java.lang.String> getNamespaceNames();
+    method @Nullable public abstract java.util.Collection<java.lang.String> getRetrievedEntryNames(@NonNull String);
+    method @NonNull public abstract byte[] getStaticAuthenticationData();
+    method public abstract int getStatus(@NonNull String, @NonNull String);
+    field public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3; // 0x3
+    field public static final int STATUS_NOT_REQUESTED = 2; // 0x2
+    field public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6; // 0x6
+    field public static final int STATUS_NO_SUCH_ENTRY = 1; // 0x1
+    field public static final int STATUS_OK = 0; // 0x0
+    field public static final int STATUS_READER_AUTHENTICATION_FAILED = 5; // 0x5
+    field public static final int STATUS_USER_AUTHENTICATION_FAILED = 4; // 0x4
+  }
+
+  public class SessionTranscriptMismatchException extends android.security.identity.IdentityCredentialException {
+    ctor public SessionTranscriptMismatchException(@NonNull String);
+    ctor public SessionTranscriptMismatchException(@NonNull String, @NonNull Throwable);
+  }
+
+  public class UnknownAuthenticationKeyException extends android.security.identity.IdentityCredentialException {
+    ctor public UnknownAuthenticationKeyException(@NonNull String);
+    ctor public UnknownAuthenticationKeyException(@NonNull String, @NonNull Throwable);
+  }
+
+  public abstract class WritableIdentityCredential {
+    ctor public WritableIdentityCredential();
+    method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain(@NonNull byte[]);
+    method @NonNull public abstract byte[] personalize(@NonNull android.security.identity.PersonalizationData);
+  }
+
+}
+
 package android.security.keystore {
 
   public class KeyExpiredException extends java.security.InvalidKeyException {
@@ -42144,13 +42579,13 @@
     method @NonNull public android.service.autofill.FillResponse build();
     method @NonNull public android.service.autofill.FillResponse.Builder disableAutofill(long);
     method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews);
-    method @NonNull public android.service.autofill.FillResponse.Builder setCancelTargetIds(@Nullable int[]);
     method @NonNull public android.service.autofill.FillResponse.Builder setClientState(@Nullable android.os.Bundle);
     method @NonNull public android.service.autofill.FillResponse.Builder setFieldClassificationIds(@NonNull android.view.autofill.AutofillId...);
     method @NonNull public android.service.autofill.FillResponse.Builder setFlags(int);
     method @NonNull public android.service.autofill.FillResponse.Builder setFooter(@NonNull android.widget.RemoteViews);
     method @NonNull public android.service.autofill.FillResponse.Builder setHeader(@NonNull android.widget.RemoteViews);
     method @NonNull public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
+    method @NonNull public android.service.autofill.FillResponse.Builder setPresentationCancelIds(@Nullable int[]);
     method @NonNull public android.service.autofill.FillResponse.Builder setSaveInfo(@NonNull android.service.autofill.SaveInfo);
     method @NonNull public android.service.autofill.FillResponse.Builder setUserData(@NonNull android.service.autofill.UserData);
   }
@@ -45019,6 +45454,8 @@
 package android.telephony {
 
   public final class AccessNetworkConstants {
+    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
+    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
   }
 
   public static final class AccessNetworkConstants.AccessNetworkType {
@@ -45367,6 +45804,7 @@
     field public static final String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
     field public static final String KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL = "allowAttachAudio";
     field public static final String KEY_MMS_APPEND_TRANSACTION_ID_BOOL = "enabledTransID";
+    field public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection";
     field public static final String KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING = "emailGatewayNumber";
     field public static final String KEY_MMS_GROUP_MMS_ENABLED_BOOL = "enableGroupMms";
     field public static final String KEY_MMS_HTTP_PARAMS_STRING = "httpParams";
@@ -45564,7 +46002,8 @@
     method public int getCellConnectionStatus();
     method @NonNull public abstract android.telephony.CellIdentity getCellIdentity();
     method @NonNull public abstract android.telephony.CellSignalStrength getCellSignalStrength();
-    method public long getTimeStamp();
+    method @Deprecated public long getTimeStamp();
+    method public long getTimestampNanos();
     method public boolean isRegistered();
     field public static final int CONNECTION_NONE = 0; // 0x0
     field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
@@ -45804,6 +46243,35 @@
     field @Deprecated public static final int UNKNOWN_RSSI = 99; // 0x63
   }
 
+  public final class NetworkRegistrationInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAccessNetworkTechnology();
+    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
+    method @Nullable public android.telephony.CellIdentity getCellIdentity();
+    method public int getDomain();
+    method public int getNrState();
+    method public int getTransportType();
+    method public boolean isRegistered();
+    method public boolean isRoaming();
+    method public boolean isSearching();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
+    field public static final int DOMAIN_CS = 1; // 0x1
+    field public static final int DOMAIN_CS_PS = 3; // 0x3
+    field public static final int DOMAIN_PS = 2; // 0x2
+    field public static final int DOMAIN_UNKNOWN = 0; // 0x0
+    field public static final int NR_STATE_CONNECTED = 3; // 0x3
+    field public static final int NR_STATE_NONE = 0; // 0x0
+    field public static final int NR_STATE_NOT_RESTRICTED = 2; // 0x2
+    field public static final int NR_STATE_RESTRICTED = 1; // 0x1
+    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
+    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
+    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
+    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
+    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
+  }
+
   public class NetworkScan {
     method public void stopScan();
     field public static final int ERROR_INTERRUPTED = 10002; // 0x2712
@@ -45978,6 +46446,7 @@
     method public int getChannelNumber();
     method public int getDuplexMode();
     method public boolean getIsManualSelection();
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
     method public String getOperatorAlphaLong();
     method public String getOperatorAlphaShort();
     method public String getOperatorNumeric();
@@ -46014,6 +46483,7 @@
     method @Deprecated public int getGsmBitErrorRate();
     method @Deprecated public int getGsmSignalStrength();
     method public int getLevel();
+    method public long getTimestampNanos();
     method @Deprecated public boolean isGsm();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SignalStrength> CREATOR;
@@ -46036,7 +46506,9 @@
     method public void sendDataMessage(String, String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
     method @Deprecated public void sendMultimediaMessage(android.content.Context, android.net.Uri, String, android.os.Bundle, android.app.PendingIntent);
     method public void sendMultipartTextMessage(String, String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, long);
     method public void sendTextMessage(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
+    method public void sendTextMessage(@NonNull String, @Nullable String, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent, long);
     method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.SEND_SMS}) public void sendTextMessageWithoutPersisting(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSmscAddress(@NonNull String);
     field public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
@@ -46408,6 +46880,7 @@
     method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
+    method public boolean isDataCapable();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
     method public boolean isEmergencyNumber(@NonNull String);
@@ -46914,6 +47387,37 @@
 
 package android.telephony.ims {
 
+  public final class ImsException extends java.lang.Exception {
+    method public int getCode();
+    field public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; // 0x1
+    field public static final int CODE_ERROR_UNSPECIFIED = 0; // 0x0
+    field public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2; // 0x2
+  }
+
+  public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
+    method @NonNull @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getVoWiFiModeSetting();
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isAdvancedCallingSettingEnabled();
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isTtyOverVolteEnabled();
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isVoWiFiRoamingSettingEnabled();
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isVoWiFiSettingEnabled();
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isVtSettingEnabled();
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public void unregisterMmTelCapabilityCallback(@NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback);
+    field public static final int WIFI_MODE_CELLULAR_PREFERRED = 1; // 0x1
+    field public static final int WIFI_MODE_WIFI_ONLY = 0; // 0x0
+    field public static final int WIFI_MODE_WIFI_PREFERRED = 2; // 0x2
+  }
+
+  public static class ImsMmTelManager.CapabilityCallback {
+    ctor public ImsMmTelManager.CapabilityCallback();
+    method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+  }
+
   public final class ImsReasonInfo implements android.os.Parcelable {
     ctor public ImsReasonInfo(int, int, @Nullable String);
     method public int describeContents();
@@ -47097,6 +47601,38 @@
     field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
   }
 
+  public interface RegistrationManager {
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+    field public static final int REGISTRATION_STATE_NOT_REGISTERED = 0; // 0x0
+    field public static final int REGISTRATION_STATE_REGISTERED = 2; // 0x2
+    field public static final int REGISTRATION_STATE_REGISTERING = 1; // 0x1
+  }
+
+  public static class RegistrationManager.RegistrationCallback {
+    ctor public RegistrationManager.RegistrationCallback();
+    method public void onRegistered(int);
+    method public void onRegistering(int);
+    method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
+    method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
+  }
+
+}
+
+package android.telephony.ims.feature {
+
+  public class MmTelFeature {
+  }
+
+  public static class MmTelFeature.MmTelCapabilities {
+    field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8
+    field public static final int CAPABILITY_TYPE_UT = 4; // 0x4
+    field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2
+    field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1
+  }
+
 }
 
 package android.telephony.mbms {
@@ -50370,6 +50906,7 @@
 
   public final class DisplayCutout {
     ctor public DisplayCutout(@NonNull android.graphics.Insets, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect);
+    ctor public DisplayCutout(@NonNull android.graphics.Insets, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, @NonNull android.graphics.Insets);
     ctor @Deprecated public DisplayCutout(@Nullable android.graphics.Rect, @Nullable java.util.List<android.graphics.Rect>);
     method @NonNull public android.graphics.Rect getBoundingRectBottom();
     method @NonNull public android.graphics.Rect getBoundingRectLeft();
@@ -50380,6 +50917,7 @@
     method public int getSafeInsetLeft();
     method public int getSafeInsetRight();
     method public int getSafeInsetTop();
+    method @NonNull public android.graphics.Insets getWaterfallInsets();
   }
 
   public final class DragAndDropPermissions implements android.os.Parcelable {
@@ -53491,9 +54029,9 @@
 
   public final class WindowInsets {
     ctor public WindowInsets(android.view.WindowInsets);
-    method @NonNull public android.view.WindowInsets consumeDisplayCutout();
-    method @NonNull public android.view.WindowInsets consumeStableInsets();
-    method @NonNull public android.view.WindowInsets consumeSystemWindowInsets();
+    method @Deprecated @NonNull public android.view.WindowInsets consumeDisplayCutout();
+    method @Deprecated @NonNull public android.view.WindowInsets consumeStableInsets();
+    method @Deprecated @NonNull public android.view.WindowInsets consumeSystemWindowInsets();
     method @Nullable public android.view.DisplayCutout getDisplayCutout();
     method @NonNull public android.graphics.Insets getInsets(int);
     method @NonNull public android.graphics.Insets getMandatorySystemGestureInsets();
@@ -53519,6 +54057,7 @@
     method public boolean isVisible(int);
     method @Deprecated @NonNull public android.view.WindowInsets replaceSystemWindowInsets(int, int, int, int);
     method @Deprecated @NonNull public android.view.WindowInsets replaceSystemWindowInsets(android.graphics.Rect);
+    field @NonNull public static final android.view.WindowInsets CONSUMED;
   }
 
   public static final class WindowInsets.Builder {
@@ -53550,10 +54089,13 @@
   }
 
   public interface WindowInsetsAnimationCallback {
+    method public int getDispatchMode();
     method public default void onFinish(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
     method public default void onPrepare(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
     method @NonNull public android.view.WindowInsets onProgress(@NonNull android.view.WindowInsets);
     method @NonNull public default android.view.WindowInsetsAnimationCallback.AnimationBounds onStart(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation, @NonNull android.view.WindowInsetsAnimationCallback.AnimationBounds);
+    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
+    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
   }
 
   public static final class WindowInsetsAnimationCallback.AnimationBounds {
@@ -53593,8 +54135,10 @@
 
   public interface WindowInsetsController {
     method public default void controlInputMethodAnimation(long, @NonNull android.view.WindowInsetsAnimationControlListener);
+    method public int getSystemBarsAppearance();
+    method public int getSystemBarsBehavior();
     method public default void hideInputMethod();
-    method public void setSystemBarsAppearance(int);
+    method public void setSystemBarsAppearance(int, int);
     method public void setSystemBarsBehavior(int);
     method public default void showInputMethod();
     field public static final int APPEARANCE_LIGHT_NAVIGATION_BARS = 16; // 0x10
@@ -53680,6 +54224,7 @@
     field public static final int LAST_SUB_WINDOW = 1999; // 0x7cf
     field public static final int LAST_SYSTEM_WINDOW = 2999; // 0xbb7
     field public static final int LAYOUT_CHANGED = 1; // 0x1
+    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 3; // 0x3
     field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0; // 0x0
     field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2; // 0x2
     field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1; // 0x1
@@ -59294,7 +59839,7 @@
     method public int getGravity();
     method public float getHorizontalMargin();
     method public float getVerticalMargin();
-    method public android.view.View getView();
+    method @Deprecated public android.view.View getView();
     method public int getXOffset();
     method public int getYOffset();
     method public static android.widget.Toast makeText(android.content.Context, CharSequence, int);
@@ -59305,7 +59850,7 @@
     method public void setMargin(float, float);
     method public void setText(@StringRes int);
     method public void setText(CharSequence);
-    method public void setView(android.view.View);
+    method @Deprecated public void setView(android.view.View);
     method public void show();
     field public static final int LENGTH_LONG = 1; // 0x1
     field public static final int LENGTH_SHORT = 0; // 0x0
@@ -71886,6 +72431,18 @@
     method public int lastIndexOf(@Nullable Object);
     method @NonNull public java.util.ListIterator<E> listIterator();
     method @NonNull public java.util.ListIterator<E> listIterator(int);
+    method @NonNull public static <E> java.util.List<E> of();
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull @java.lang.SafeVarargs public static <E> java.util.List<E> of(@NonNull E...);
     method public E remove(int);
     method public default void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
     method public E set(int, E);
@@ -72040,6 +72597,7 @@
     method @Nullable public default V computeIfPresent(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
     method public boolean containsKey(@Nullable Object);
     method public boolean containsValue(@Nullable Object);
+    method @NonNull public static <K, V> java.util.Map.Entry<K,V> entry(@NonNull K, @NonNull V);
     method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
     method public boolean equals(@Nullable Object);
     method public default void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
@@ -72049,6 +72607,18 @@
     method public boolean isEmpty();
     method @NonNull public java.util.Set<K> keySet();
     method @Nullable public default V merge(K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
+    method @NonNull public static <K, V> java.util.Map<K,V> of();
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull @java.lang.SafeVarargs public static <K, V> java.util.Map<K,V> ofEntries(@NonNull java.util.Map.Entry<? extends K,? extends V>...);
     method @Nullable public V put(K, V);
     method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
     method @Nullable public default V putIfAbsent(K, V);
@@ -72130,6 +72700,9 @@
   }
 
   public final class Objects {
+    method public static int checkFromIndexSize(int, int, int);
+    method public static int checkFromToIndex(int, int, int);
+    method public static int checkIndex(int, int);
     method public static <T> int compare(T, T, @NonNull java.util.Comparator<? super T>);
     method public static boolean deepEquals(@Nullable Object, @Nullable Object);
     method public static boolean equals(@Nullable Object, @Nullable Object);
@@ -72140,6 +72713,8 @@
     method @NonNull public static <T> T requireNonNull(@Nullable T);
     method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull String);
     method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull java.util.function.Supplier<java.lang.String>);
+    method @NonNull public static <T> T requireNonNullElse(@Nullable T, @NonNull T);
+    method @NonNull public static <T> T requireNonNullElseGet(@Nullable T, @NonNull java.util.function.Supplier<? extends T>);
     method @NonNull public static String toString(@Nullable Object);
     method @NonNull public static String toString(@Nullable Object, @NonNull String);
   }
@@ -72444,6 +73019,18 @@
   }
 
   public interface Set<E> extends java.util.Collection<E> {
+    method @NonNull public static <E> java.util.Set<E> of();
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull @java.lang.SafeVarargs public static <E> java.util.Set<E> of(@NonNull E...);
   }
 
   public class SimpleTimeZone extends java.util.TimeZone {
@@ -73382,6 +73969,29 @@
     method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
   }
 
+  public final class Flow {
+    method public static int defaultBufferSize();
+  }
+
+  public static interface Flow.Processor<T, R> extends java.util.concurrent.Flow.Subscriber<T> java.util.concurrent.Flow.Publisher<R> {
+  }
+
+  @java.lang.FunctionalInterface public static interface Flow.Publisher<T> {
+    method public void subscribe(java.util.concurrent.Flow.Subscriber<? super T>);
+  }
+
+  public static interface Flow.Subscriber<T> {
+    method public void onComplete();
+    method public void onError(Throwable);
+    method public void onNext(T);
+    method public void onSubscribe(java.util.concurrent.Flow.Subscription);
+  }
+
+  public static interface Flow.Subscription {
+    method public void cancel();
+    method public void request(long);
+  }
+
   public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
     ctor public ForkJoinPool();
     ctor public ForkJoinPool(int);
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 508718e..2a8f04f 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -505,10 +505,20 @@
     
 MissingNullability: android.app.SyncNotedAppOp#equals(Object) parameter #0:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#CHORASMIAN:
+    Missing nullability on field `CHORASMIAN` in class `class android.icu.lang.UCharacter.UnicodeBlock`
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G:
+    Missing nullability on field `CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G` in class `class android.icu.lang.UCharacter.UnicodeBlock`
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#DIVES_AKURU:
+    Missing nullability on field `DIVES_AKURU` in class `class android.icu.lang.UCharacter.UnicodeBlock`
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS:
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#ELYMAIC:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#KHITAN_SMALL_SCRIPT:
+    
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#LISU_SUPPLEMENT:
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NANDINAGARI:
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NYIAKENG_PUACHUE_HMONG:
@@ -519,26 +529,34 @@
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_FOR_LEGACY_COMPUTING:
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TAMIL_SUPPLEMENT:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TANGUT_SUPPLEMENT:
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#WANCHO:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#YEZIDI:
+    
 MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth):
     
 MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth) parameter #1:
     
 MissingNullability: android.icu.util.MeasureUnit#ATMOSPHERE:
-    Missing nullability on field `ATMOSPHERE` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.MeasureUnit#PERCENT:
-    Missing nullability on field `PERCENT` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.MeasureUnit#PERMILLE:
-    Missing nullability on field `PERMILLE` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.MeasureUnit#PETABYTE:
-    Missing nullability on field `PETABYTE` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.VersionInfo#UNICODE_12_0:
     
 MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1:
     
+MissingNullability: android.icu.util.VersionInfo#UNICODE_13_0:
+    Missing nullability on field `UNICODE_13_0` in class `class android.icu.util.VersionInfo`
 MissingNullability: android.media.MediaMetadataRetriever#getFrameAtTime(long, int, android.media.MediaMetadataRetriever.BitmapParams):
     
 MissingNullability: android.media.MediaMetadataRetriever#getScaledFrameAtTime(long, int, int, int, android.media.MediaMetadataRetriever.BitmapParams):
diff --git a/api/system-current.txt b/api/system-current.txt
index e532a3a..f95f715 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -67,6 +67,7 @@
     field public static final String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
     field public static final String CONTROL_KEYGUARD_SECURE_NOTIFICATIONS = "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS";
     field public static final String CONTROL_VPN = "android.permission.CONTROL_VPN";
+    field public static final String CREATE_USERS = "android.permission.CREATE_USERS";
     field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
     field public static final String DEVICE_POWER = "android.permission.DEVICE_POWER";
     field public static final String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE";
@@ -155,6 +156,7 @@
     field public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
     field public static final String RADIO_SCAN_WITHOUT_LOCATION = "android.permission.RADIO_SCAN_WITHOUT_LOCATION";
     field public static final String READ_ACTIVE_EMERGENCY_SESSION = "android.permission.READ_ACTIVE_EMERGENCY_SESSION";
+    field public static final String READ_CARRIER_APP_INFO = "android.permission.READ_CARRIER_APP_INFO";
     field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
     field public static final String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
     field public static final String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG";
@@ -326,11 +328,15 @@
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
     method @NonNull public java.util.Collection<java.util.Locale> getSupportedLocales();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isProfileForeground(@NonNull android.os.UserHandle);
+    method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void killProcessesWhenImperceptible(@NonNull int[], @NonNull String);
     method @RequiresPermission(android.Manifest.permission.KILL_UID) public void killUid(int, String);
+    method public void registerHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public void setDeviceLocales(@NonNull android.os.LocaleList);
     method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle);
+    method public void unregisterHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
   }
 
@@ -566,6 +572,10 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.PackageOps> CREATOR;
   }
 
+  public final class ApplicationExitInfo implements android.os.Parcelable {
+    method @NonNull public android.os.UserHandle getUserHandle();
+  }
+
   public class BroadcastOptions {
     method public static android.app.BroadcastOptions makeBasic();
     method @RequiresPermission("android.permission.START_ACTIVITIES_FROM_BACKGROUND") public void setBackgroundActivityStartsAllowed(boolean);
@@ -579,6 +589,11 @@
     field public static final String ACTION_DOWNLOAD_COMPLETED = "android.intent.action.DOWNLOAD_COMPLETED";
   }
 
+  public abstract class HomeVisibilityObserver {
+    ctor public HomeVisibilityObserver();
+    method public abstract void onHomeVisibilityChanged(boolean);
+  }
+
   public abstract class InstantAppResolverService extends android.app.Service {
     ctor public InstantAppResolverService();
     method public final void attachBaseContext(android.content.Context);
@@ -661,6 +676,7 @@
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
+    method public void registerPullAtomCallback(int, @Nullable android.app.StatsManager.PullAtomMetadata, @NonNull java.util.concurrent.Executor, @NonNull android.app.StatsManager.StatsPullAtomCallback);
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
     method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
@@ -668,6 +684,7 @@
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
+    method public void unregisterPullAtomCallback(int);
     field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
     field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
     field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
@@ -676,6 +693,23 @@
     field public static final String EXTRA_STATS_DIMENSIONS_VALUE = "android.app.extra.STATS_DIMENSIONS_VALUE";
     field public static final String EXTRA_STATS_SUBSCRIPTION_ID = "android.app.extra.STATS_SUBSCRIPTION_ID";
     field public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
+    field public static final int PULL_SKIP = 1; // 0x1
+    field public static final int PULL_SUCCESS = 0; // 0x0
+  }
+
+  public static class StatsManager.PullAtomMetadata {
+  }
+
+  public static class StatsManager.PullAtomMetadata.Builder {
+    ctor public StatsManager.PullAtomMetadata.Builder();
+    method @NonNull public android.app.StatsManager.PullAtomMetadata build();
+    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setAdditiveFields(@NonNull int[]);
+    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setCoolDownNs(long);
+    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setTimeoutNs(long);
+  }
+
+  public static interface StatsManager.StatsPullAtomCallback {
+    method public int onPullAtom(int, @NonNull java.util.List<android.util.StatsEvent>);
   }
 
   public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
@@ -1728,6 +1762,7 @@
     field public static final String SECURE_ELEMENT_SERVICE = "secure_element";
     field public static final String STATS_MANAGER = "stats";
     field public static final String STATUS_BAR_SERVICE = "statusbar";
+    field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
     field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
     field public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
     field public static final String TELEPHONY_REGISTRY_SERVICE = "telephony_registry";
@@ -1800,6 +1835,7 @@
     field public static final String EXTRA_PERMISSION_GROUP_NAME = "android.intent.extra.PERMISSION_GROUP_NAME";
     field public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
     field public static final String EXTRA_REASON = "android.intent.extra.REASON";
+    field @Deprecated public static final String EXTRA_REBROADCAST_ON_UNLOCK = "rebroadcastOnUnlock";
     field public static final String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
     field public static final String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
     field public static final String EXTRA_ROLE_NAME = "android.intent.extra.ROLE_NAME";
@@ -2092,6 +2128,10 @@
 
   public class PackageInstaller {
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
+    field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
+    field public static final int DATA_LOADER_TYPE_NONE = 0; // 0x0
+    field public static final int DATA_LOADER_TYPE_STREAMING = 1; // 0x1
+    field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
   }
 
   public static class PackageInstaller.Session implements java.io.Closeable {
@@ -4631,9 +4671,28 @@
 
 package android.media.tv.tuner {
 
-  public abstract class FrontendSettings {
-    method public final int getFrequency();
-    method public abstract int getType();
+  public class DemuxCapabilities {
+    method public int getAudioFilterCount();
+    method public int getDemuxCount();
+    method public int getFilterCapabilities();
+    method @Nullable @Size(5) public int[] getLinkCapabilities();
+    method public int getPcrFilterCount();
+    method public int getPesFilterCount();
+    method public int getPlaybackCount();
+    method public int getRecordCount();
+    method public int getSectionFilterCount();
+    method public long getSectionFilterLength();
+    method public int getTsFilterCount();
+    method public int getVideoFilterCount();
+  }
+
+  public class Descrambler implements java.lang.AutoCloseable {
+    method public int addPid(int, int, @Nullable android.media.tv.tuner.filter.Filter);
+    method public void close();
+    method public int removePid(int, int, @Nullable android.media.tv.tuner.filter.Filter);
+    method public int setKeyToken(@Nullable byte[]);
+    field public static final int PID_TYPE_MMTP = 2; // 0x2
+    field public static final int PID_TYPE_T = 1; // 0x1
   }
 
   public class Lnb implements java.lang.AutoCloseable {
@@ -4642,6 +4701,10 @@
     method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int setSatellitePosition(int);
     method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int setTone(int);
     method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int setVoltage(int);
+    field public static final int EVENT_TYPE_DISEQC_RX_OVERFLOW = 0; // 0x0
+    field public static final int EVENT_TYPE_DISEQC_RX_PARITY_ERROR = 2; // 0x2
+    field public static final int EVENT_TYPE_DISEQC_RX_TIMEOUT = 1; // 0x1
+    field public static final int EVENT_TYPE_LNB_OVERLOAD = 3; // 0x3
     field public static final int POSITION_A = 1; // 0x1
     field public static final int POSITION_B = 2; // 0x2
     field public static final int POSITION_UNDEFINED = 0; // 0x0
@@ -4658,28 +4721,32 @@
     field public static final int VOLTAGE_NONE = 0; // 0x0
   }
 
+  public interface LnbCallback {
+    method public void onDiseqcMessage(@NonNull byte[]);
+    method public void onEvent(int);
+  }
+
   public final class Tuner implements java.lang.AutoCloseable {
     ctor public Tuner(@NonNull android.content.Context);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void clearOnTuneEventListener();
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.Tuner.Descrambler openDescrambler();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int tune(@NonNull android.media.tv.tuner.FrontendSettings);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.dvr.DvrPlayback openDvrPlayback(long, @Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.dvr.DvrRecorder openDvrRecorder(long, @Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.dvr.OnRecordStatusChangedListener);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.filter.Filter openFilter(int, int, long, @Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.filter.FilterCallback);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.Lnb openLnb(@Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.LnbCallback);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.Lnb openLnbByName(@Nullable String, @Nullable java.util.concurrent.Executor, @NonNull android.media.tv.tuner.LnbCallback);
+    method @Nullable public android.media.tv.tuner.filter.TimeFilter openTimeFilter();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int scan(@NonNull android.media.tv.tuner.frontend.FrontendSettings, int, @NonNull java.util.concurrent.Executor, @NonNull android.media.tv.tuner.frontend.ScanCallback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void setOnTuneEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.tuner.frontend.OnTuneEventListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int stopScan();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int stopTune();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int tune(@NonNull android.media.tv.tuner.frontend.FrontendSettings);
   }
 
   public class Tuner.Descrambler {
   }
 
-  public class Tuner.Filter {
-  }
-
-  public static interface Tuner.FilterCallback {
-    method public void onFilterEvent(@NonNull android.media.tv.tuner.Tuner.Filter, @NonNull android.media.tv.tuner.filter.FilterEvent[]);
-    method public void onFilterStatusChanged(@NonNull android.media.tv.tuner.Tuner.Filter, int);
-  }
-
   public final class TunerConstants {
-    field public static final int FILTER_STATUS_DATA_READY = 1; // 0x1
-    field public static final int FILTER_STATUS_HIGH_WATER = 4; // 0x4
-    field public static final int FILTER_STATUS_LOW_WATER = 2; // 0x2
-    field public static final int FILTER_STATUS_OVERFLOW = 8; // 0x8
     field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
     field public static final int RESULT_INVALID_STATE = 3; // 0x3
     field public static final int RESULT_NOT_INITIALIZED = 2; // 0x2
@@ -4687,24 +4754,259 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
     field public static final int RESULT_UNAVAILABLE = 1; // 0x1
     field public static final int RESULT_UNKNOWN_ERROR = 6; // 0x6
+    field public static final int SCAN_TYPE_AUTO = 1; // 0x1
+    field public static final int SCAN_TYPE_BLIND = 2; // 0x2
+    field public static final int SCAN_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int SC_HEVC_INDEX_AUD = 2; // 0x2
+    field public static final int SC_HEVC_INDEX_SLICE_BLA_N_LP = 16; // 0x10
+    field public static final int SC_HEVC_INDEX_SLICE_BLA_W_RADL = 8; // 0x8
+    field public static final int SC_HEVC_INDEX_SLICE_CE_BLA_W_LP = 4; // 0x4
+    field public static final int SC_HEVC_INDEX_SLICE_IDR_N_LP = 64; // 0x40
+    field public static final int SC_HEVC_INDEX_SLICE_IDR_W_RADL = 32; // 0x20
+    field public static final int SC_HEVC_INDEX_SLICE_TRAIL_CRA = 128; // 0x80
+    field public static final int SC_HEVC_INDEX_SPS = 1; // 0x1
+    field public static final int SC_INDEX_B_FRAME = 4; // 0x4
+    field public static final int SC_INDEX_I_FRAME = 1; // 0x1
+    field public static final int SC_INDEX_P_FRAME = 2; // 0x2
+    field public static final int SC_INDEX_SEQUENCE = 8; // 0x8
+  }
+
+}
+
+package android.media.tv.tuner.dvr {
+
+  public class Dvr implements java.lang.AutoCloseable {
+    ctor protected Dvr(int);
+    method public int attachFilter(@NonNull android.media.tv.tuner.filter.Filter);
+    method public void close();
+    method public int configure(@NonNull android.media.tv.tuner.dvr.DvrSettings);
+    method public int detachFilter(@NonNull android.media.tv.tuner.filter.Filter);
+    method public int flush();
+    method public void setFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
+    method public int start();
+    method public int stop();
+    field public static final int TYPE_PLAYBACK = 1; // 0x1
+    field public static final int TYPE_RECORD = 0; // 0x0
+  }
+
+  public class DvrPlayback extends android.media.tv.tuner.dvr.Dvr {
+    method public long read(long);
+    method public long read(@NonNull byte[], long, long);
+    field public static final int PLAYBACK_STATUS_ALMOST_EMPTY = 2; // 0x2
+    field public static final int PLAYBACK_STATUS_ALMOST_FULL = 4; // 0x4
+    field public static final int PLAYBACK_STATUS_EMPTY = 1; // 0x1
+    field public static final int PLAYBACK_STATUS_FULL = 8; // 0x8
+  }
+
+  public class DvrRecorder extends android.media.tv.tuner.dvr.Dvr {
+    method public long write(long);
+    method public long write(@NonNull byte[], long, long);
+  }
+
+  public class DvrSettings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.dvr.DvrSettings.Builder builder(@NonNull android.content.Context);
+    method public int getDataFormat();
+    method public long getHighThreshold();
+    method public long getLowThreshold();
+    method public long getPacketSize();
+    method public int getStatusMask();
+    field public static final int DATA_FORMAT_ES = 2; // 0x2
+    field public static final int DATA_FORMAT_PES = 1; // 0x1
+    field public static final int DATA_FORMAT_SHV_TLV = 3; // 0x3
+    field public static final int DATA_FORMAT_TS = 0; // 0x0
+  }
+
+  public static final class DvrSettings.Builder {
+    ctor public DvrSettings.Builder();
+    method @NonNull public android.media.tv.tuner.dvr.DvrSettings build();
+    method @NonNull public android.media.tv.tuner.dvr.DvrSettings.Builder setDataFormat(int);
+    method @NonNull public android.media.tv.tuner.dvr.DvrSettings.Builder setHighThreshold(long);
+    method @NonNull public android.media.tv.tuner.dvr.DvrSettings.Builder setLowThreshold(long);
+    method @NonNull public android.media.tv.tuner.dvr.DvrSettings.Builder setPacketSize(long);
+    method @NonNull public android.media.tv.tuner.dvr.DvrSettings.Builder setStatusMask(int);
+  }
+
+  public interface OnPlaybackStatusChangedListener {
+    method public void onPlaybackStatusChanged(int);
+  }
+
+  public interface OnRecordStatusChangedListener {
+    method public void onRecordStatusChanged(int);
   }
 
 }
 
 package android.media.tv.tuner.filter {
 
+  public class AlpFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.AlpFilterConfiguration.Builder builder(@NonNull android.content.Context);
+    method public int getLengthType();
+    method public int getPacketType();
+    method public int getType();
+    field public static final int LENGTH_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int LENGTH_TYPE_WITHOUT_ADDITIONAL_HEADER = 1; // 0x1
+    field public static final int LENGTH_TYPE_WITH_ADDITIONAL_HEADER = 2; // 0x2
+  }
+
+  public static class AlpFilterConfiguration.Builder extends android.media.tv.tuner.filter.FilterConfiguration.Builder<android.media.tv.tuner.filter.AlpFilterConfiguration.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.AlpFilterConfiguration build();
+    method @NonNull public android.media.tv.tuner.filter.AlpFilterConfiguration.Builder setLengthType(int);
+    method @NonNull public android.media.tv.tuner.filter.AlpFilterConfiguration.Builder setPacketType(int);
+  }
+
+  public class AudioDescriptor {
+    method public byte getAdFade();
+    method public byte getAdGainCenter();
+    method public byte getAdGainFront();
+    method public byte getAdGainSurround();
+    method public byte getAdPan();
+    method public char getAdVersionTextTag();
+  }
+
+  public class AvSettings extends android.media.tv.tuner.filter.Settings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.AvSettings.Builder builder(@NonNull android.content.Context, int, boolean);
+    method public boolean isPassthrough();
+  }
+
+  public static class AvSettings.Builder extends android.media.tv.tuner.filter.Settings.Builder<android.media.tv.tuner.filter.AvSettings.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.AvSettings build();
+    method @NonNull public android.media.tv.tuner.filter.AvSettings.Builder setPassthrough(boolean);
+  }
+
+  public class DownloadEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method public int getDataLength();
+    method public int getItemFragmentIndex();
+    method public int getItemId();
+    method public int getLastItemFragmentIndex();
+    method public int getMpuSequenceNumber();
+  }
+
+  public class DownloadSettings extends android.media.tv.tuner.filter.Settings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.DownloadSettings.Builder builder(@NonNull android.content.Context, int);
+    method public int getDownloadId();
+  }
+
+  public static class DownloadSettings.Builder extends android.media.tv.tuner.filter.Settings.Builder<android.media.tv.tuner.filter.DownloadSettings.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.DownloadSettings build();
+    method @NonNull public android.media.tv.tuner.filter.DownloadSettings.Builder setDownloadId(int);
+  }
+
+  public class Filter implements java.lang.AutoCloseable {
+    method public void close();
+    method public int configure(@NonNull android.media.tv.tuner.filter.FilterConfiguration);
+    method public int flush();
+    method public int getId();
+    method public int read(@NonNull byte[], long, long);
+    method public int setDataSource(@Nullable android.media.tv.tuner.filter.Filter);
+    method public int start();
+    method public int stop();
+    field public static final int STATUS_DATA_READY = 1; // 0x1
+    field public static final int STATUS_HIGH_WATER = 4; // 0x4
+    field public static final int STATUS_LOW_WATER = 2; // 0x2
+    field public static final int STATUS_OVERFLOW = 8; // 0x8
+    field public static final int SUBTYPE_AUDIO = 3; // 0x3
+    field public static final int SUBTYPE_DOWNLOAD = 5; // 0x5
+    field public static final int SUBTYPE_IP = 13; // 0xd
+    field public static final int SUBTYPE_IP_PAYLOAD = 12; // 0xc
+    field public static final int SUBTYPE_MMTP = 10; // 0xa
+    field public static final int SUBTYPE_NTP = 11; // 0xb
+    field public static final int SUBTYPE_PAYLOAD_THROUGH = 14; // 0xe
+    field public static final int SUBTYPE_PCR = 8; // 0x8
+    field public static final int SUBTYPE_PES = 2; // 0x2
+    field public static final int SUBTYPE_PTP = 16; // 0x10
+    field public static final int SUBTYPE_RECORD = 6; // 0x6
+    field public static final int SUBTYPE_SECTION = 1; // 0x1
+    field public static final int SUBTYPE_TEMI = 9; // 0x9
+    field public static final int SUBTYPE_TLV = 15; // 0xf
+    field public static final int SUBTYPE_TS = 7; // 0x7
+    field public static final int SUBTYPE_UNDEFINED = 0; // 0x0
+    field public static final int SUBTYPE_VIDEO = 4; // 0x4
+    field public static final int TYPE_ALP = 16; // 0x10
+    field public static final int TYPE_IP = 4; // 0x4
+    field public static final int TYPE_MMTP = 2; // 0x2
+    field public static final int TYPE_TLV = 8; // 0x8
+    field public static final int TYPE_TS = 1; // 0x1
+  }
+
+  public interface FilterCallback {
+    method public void onFilterEvent(@NonNull android.media.tv.tuner.filter.Filter, @NonNull android.media.tv.tuner.filter.FilterEvent[]);
+    method public void onFilterStatusChanged(@NonNull android.media.tv.tuner.filter.Filter, int);
+  }
+
   public abstract class FilterConfiguration {
-    field public static final int FILTER_TYPE_ALP = 16; // 0x10
-    field public static final int FILTER_TYPE_IP = 4; // 0x4
-    field public static final int FILTER_TYPE_MMTP = 2; // 0x2
-    field public static final int FILTER_TYPE_TLV = 8; // 0x8
-    field public static final int FILTER_TYPE_TS = 1; // 0x1
+    method @Nullable public android.media.tv.tuner.filter.Settings getSettings();
+    method public abstract int getType();
+    field public static final int PACKET_TYPE_COMPRESSED = 2; // 0x2
+    field public static final int PACKET_TYPE_IPV4 = 0; // 0x0
+    field public static final int PACKET_TYPE_SIGNALING = 4; // 0x4
+  }
+
+  public abstract static class FilterConfiguration.Builder<T extends android.media.tv.tuner.filter.FilterConfiguration.Builder<T>> {
+    method @NonNull public T setSettings(@Nullable android.media.tv.tuner.filter.Settings);
   }
 
   public abstract class FilterEvent {
     ctor public FilterEvent();
   }
 
+  public class IpFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.IpFilterConfiguration.Builder builder(@NonNull android.content.Context);
+    method @NonNull @Size(min=4, max=16) public byte[] getDstIpAddress();
+    method public int getDstPort();
+    method @NonNull @Size(min=4, max=16) public byte[] getSrcIpAddress();
+    method public int getSrcPort();
+    method public int getType();
+    method public boolean isPassthrough();
+  }
+
+  public static class IpFilterConfiguration.Builder extends android.media.tv.tuner.filter.FilterConfiguration.Builder<android.media.tv.tuner.filter.IpFilterConfiguration.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.IpFilterConfiguration build();
+    method @NonNull public android.media.tv.tuner.filter.IpFilterConfiguration.Builder setDstIpAddress(@NonNull byte[]);
+    method @NonNull public android.media.tv.tuner.filter.IpFilterConfiguration.Builder setDstPort(int);
+    method @NonNull public android.media.tv.tuner.filter.IpFilterConfiguration.Builder setPassthrough(boolean);
+    method @NonNull public android.media.tv.tuner.filter.IpFilterConfiguration.Builder setSrcIpAddress(@NonNull byte[]);
+    method @NonNull public android.media.tv.tuner.filter.IpFilterConfiguration.Builder setSrcPort(int);
+  }
+
+  public class IpPayloadEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method public int getDataLength();
+  }
+
+  public class MediaEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method public long getAvDataId();
+    method public long getDataLength();
+    method @Nullable public android.media.tv.tuner.filter.AudioDescriptor getExtraMetaData();
+    method public int getMpuSequenceNumber();
+    method public long getOffset();
+    method public long getPts();
+    method public int getStreamId();
+    method public boolean isPrivateData();
+    method public boolean isPtsPresent();
+    method public boolean isSecureMemory();
+  }
+
+  public class MmtpFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.MmtpFilterConfiguration.Builder builder(@NonNull android.content.Context);
+    method public int getMmtpPacketId();
+    method public int getType();
+  }
+
+  public static class MmtpFilterConfiguration.Builder extends android.media.tv.tuner.filter.FilterConfiguration.Builder<android.media.tv.tuner.filter.MmtpFilterConfiguration.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.MmtpFilterConfiguration build();
+    method @NonNull public android.media.tv.tuner.filter.MmtpFilterConfiguration.Builder setMmtpPacketId(int);
+  }
+
+  public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method public long getDataLength();
+    method public int getScHevcIndexMask();
+  }
+
+  public class PesEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method public int getDataLength();
+    method public int getMpuSequenceNumber();
+    method public int getStreamId();
+  }
+
   public class PesSettings extends android.media.tv.tuner.filter.Settings {
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.PesSettings.Builder builder(@NonNull android.content.Context, int);
     method public int getStreamId();
@@ -4717,6 +5019,33 @@
     method @NonNull public android.media.tv.tuner.filter.PesSettings.Builder setStreamId(int);
   }
 
+  public class RecordSettings extends android.media.tv.tuner.filter.Settings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.RecordSettings.Builder builder(@NonNull android.content.Context, int);
+    method public int getScIndexMask();
+    method public int getScIndexType();
+    method public int getTsIndexMask();
+    field public static final int TS_INDEX_ADAPTATION_EXTENSION_FLAG = 4096; // 0x1000
+    field public static final int TS_INDEX_CHANGE_TO_EVEN_SCRAMBLED = 8; // 0x8
+    field public static final int TS_INDEX_CHANGE_TO_NOT_SCRAMBLED = 4; // 0x4
+    field public static final int TS_INDEX_CHANGE_TO_ODD_SCRAMBLED = 16; // 0x10
+    field public static final int TS_INDEX_DISCONTINUITY_INDICATOR = 32; // 0x20
+    field public static final int TS_INDEX_FIRST_PACKET = 1; // 0x1
+    field public static final int TS_INDEX_OPCR_FLAG = 512; // 0x200
+    field public static final int TS_INDEX_PAYLOAD_UNIT_START_INDICATOR = 2; // 0x2
+    field public static final int TS_INDEX_PCR_FLAG = 256; // 0x100
+    field public static final int TS_INDEX_PRIORITY_INDICATOR = 128; // 0x80
+    field public static final int TS_INDEX_PRIVATE_DATA = 2048; // 0x800
+    field public static final int TS_INDEX_RANDOM_ACCESS_INDICATOR = 64; // 0x40
+    field public static final int TS_INDEX_SPLICING_POINT_FLAG = 1024; // 0x400
+  }
+
+  public static class RecordSettings.Builder extends android.media.tv.tuner.filter.Settings.Builder<android.media.tv.tuner.filter.RecordSettings.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.RecordSettings build();
+    method @NonNull public android.media.tv.tuner.filter.RecordSettings.Builder setScIndexMask(int);
+    method @NonNull public android.media.tv.tuner.filter.RecordSettings.Builder setScIndexType(int);
+    method @NonNull public android.media.tv.tuner.filter.RecordSettings.Builder setTsIndexMask(int);
+  }
+
   public class SectionEvent extends android.media.tv.tuner.filter.FilterEvent {
     method public int getDataLength();
     method public int getSectionNumber();
@@ -4724,12 +5053,74 @@
     method public int getVersion();
   }
 
+  public class SectionSettings extends android.media.tv.tuner.filter.Settings {
+  }
+
+  public class SectionSettingsWithSectionBits extends android.media.tv.tuner.filter.SectionSettings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.SectionSettingsWithSectionBits.Builder builder(@NonNull android.content.Context, int);
+    method @NonNull public byte[] getFilterBytes();
+    method @NonNull public byte[] getMask();
+    method @NonNull public byte[] getMode();
+  }
+
+  public static class SectionSettingsWithSectionBits.Builder extends android.media.tv.tuner.filter.Settings.Builder<android.media.tv.tuner.filter.SectionSettingsWithSectionBits.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithSectionBits build();
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithSectionBits.Builder setFilter(@NonNull byte[]);
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithSectionBits.Builder setMask(@NonNull byte[]);
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithSectionBits.Builder setMode(@NonNull byte[]);
+  }
+
+  public class SectionSettingsWithTableInfo extends android.media.tv.tuner.filter.SectionSettings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.SectionSettingsWithTableInfo.Builder builder(@NonNull android.content.Context, int);
+    method public int getTableId();
+    method public int getVersion();
+  }
+
+  public static class SectionSettingsWithTableInfo.Builder extends android.media.tv.tuner.filter.Settings.Builder<android.media.tv.tuner.filter.SectionSettingsWithTableInfo.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithTableInfo build();
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithTableInfo.Builder setTableId(int);
+    method @NonNull public android.media.tv.tuner.filter.SectionSettingsWithTableInfo.Builder setVersion(int);
+  }
+
   public abstract class Settings {
+    method public int getType();
+  }
+
+  public abstract static class Settings.Builder<T extends android.media.tv.tuner.filter.Settings.Builder<T>> {
+  }
+
+  public class TemiEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method @NonNull public byte[] getDescriptorData();
+    method public byte getDescriptorTag();
+    method public long getPts();
+  }
+
+  public class TimeFilter implements java.lang.AutoCloseable {
+    method public int clearTimestamp();
+    method public void close();
+    method public long getSourceTime();
+    method public long getTimeStamp();
+    method public int setCurrentTimestamp(long);
+    field public static final long TIMESTAMP_UNAVAILABLE = -1L; // 0xffffffffffffffffL
+  }
+
+  public class TlvFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.TlvFilterConfiguration.Builder builder(@NonNull android.content.Context);
+    method public int getPacketType();
+    method public int getType();
+    method public boolean isCompressedIpPacket();
+    method public boolean isPassthrough();
+  }
+
+  public static class TlvFilterConfiguration.Builder extends android.media.tv.tuner.filter.FilterConfiguration.Builder<android.media.tv.tuner.filter.TlvFilterConfiguration.Builder> {
+    method @NonNull public android.media.tv.tuner.filter.TlvFilterConfiguration build();
+    method @NonNull public android.media.tv.tuner.filter.TlvFilterConfiguration.Builder setIsCompressedIpPacket(boolean);
+    method @NonNull public android.media.tv.tuner.filter.TlvFilterConfiguration.Builder setPacketType(int);
+    method @NonNull public android.media.tv.tuner.filter.TlvFilterConfiguration.Builder setPassthrough(boolean);
   }
 
   public class TsFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.filter.TsFilterConfiguration.Builder builder(@NonNull android.content.Context);
-    method @Nullable public android.media.tv.tuner.filter.Settings getSettings();
     method public int getTpid();
     method public int getType();
   }
@@ -4740,6 +5131,106 @@
     method @NonNull public android.media.tv.tuner.filter.TsFilterConfiguration.Builder setTpid(int);
   }
 
+  public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent {
+    method public long getDataLength();
+    method public int getPacketId();
+    method public int getScIndexMask();
+    method public int getTsIndexMask();
+  }
+
+}
+
+package android.media.tv.tuner.frontend {
+
+  public class AnalogFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.frontend.AnalogFrontendSettings.Builder builder(@NonNull android.content.Context);
+    method public int getSifStandard();
+    method public int getSignalType();
+    method public int getType();
+    field public static final int SIF_AUTO = 1; // 0x1
+    field public static final int SIF_BG = 2; // 0x2
+    field public static final int SIF_BG_A2 = 4; // 0x4
+    field public static final int SIF_BG_NICAM = 8; // 0x8
+    field public static final int SIF_DK = 32; // 0x20
+    field public static final int SIF_DK1_A2 = 64; // 0x40
+    field public static final int SIF_DK2_A2 = 128; // 0x80
+    field public static final int SIF_DK3_A2 = 256; // 0x100
+    field public static final int SIF_DK_NICAM = 512; // 0x200
+    field public static final int SIF_I = 16; // 0x10
+    field public static final int SIF_I_NICAM = 32768; // 0x8000
+    field public static final int SIF_L = 1024; // 0x400
+    field public static final int SIF_L_NICAM = 65536; // 0x10000
+    field public static final int SIF_L_PRIME = 131072; // 0x20000
+    field public static final int SIF_M = 2048; // 0x800
+    field public static final int SIF_M_A2 = 8192; // 0x2000
+    field public static final int SIF_M_BTSC = 4096; // 0x1000
+    field public static final int SIF_M_EIAJ = 16384; // 0x4000
+    field public static final int SIF_UNDEFINED = 0; // 0x0
+    field public static final int SIGNAL_TYPE_AUTO = 1; // 0x1
+    field public static final int SIGNAL_TYPE_NTSC = 32; // 0x20
+    field public static final int SIGNAL_TYPE_NTSC_443 = 64; // 0x40
+    field public static final int SIGNAL_TYPE_PAL = 2; // 0x2
+    field public static final int SIGNAL_TYPE_PAL_60 = 16; // 0x10
+    field public static final int SIGNAL_TYPE_PAL_M = 4; // 0x4
+    field public static final int SIGNAL_TYPE_PAL_N = 8; // 0x8
+    field public static final int SIGNAL_TYPE_SECAM = 128; // 0x80
+    field public static final int SIGNAL_TYPE_UNDEFINED = 0; // 0x0
+  }
+
+  public static class AnalogFrontendSettings.Builder extends android.media.tv.tuner.frontend.FrontendSettings.Builder<android.media.tv.tuner.frontend.AnalogFrontendSettings.Builder> {
+    method @NonNull public android.media.tv.tuner.frontend.AnalogFrontendSettings build();
+    method @NonNull public android.media.tv.tuner.frontend.AnalogFrontendSettings.Builder setASignalType(int);
+    method @NonNull public android.media.tv.tuner.frontend.AnalogFrontendSettings.Builder setSifStandard(int);
+  }
+
+  public class Atsc3PlpInfo {
+    method public boolean getLlsFlag();
+    method public int getPlpId();
+  }
+
+  public abstract class FrontendSettings {
+    method public int getFrequency();
+    method public abstract int getType();
+    field public static final int TYPE_ANALOG = 1; // 0x1
+    field public static final int TYPE_ATSC = 2; // 0x2
+    field public static final int TYPE_ATSC3 = 3; // 0x3
+    field public static final int TYPE_DVBC = 4; // 0x4
+    field public static final int TYPE_DVBS = 5; // 0x5
+    field public static final int TYPE_DVBT = 6; // 0x6
+    field public static final int TYPE_ISDBS = 7; // 0x7
+    field public static final int TYPE_ISDBS3 = 8; // 0x8
+    field public static final int TYPE_ISDBT = 9; // 0x9
+    field public static final int TYPE_UNDEFINED = 0; // 0x0
+  }
+
+  public abstract static class FrontendSettings.Builder<T extends android.media.tv.tuner.frontend.FrontendSettings.Builder<T>> {
+    method @IntRange(from=1) @NonNull public T setFrequency(int);
+  }
+
+  public interface OnTuneEventListener {
+    method public void onTuneEvent(int);
+    field public static final int SIGNAL_LOCKED = 0; // 0x0
+    field public static final int SIGNAL_LOST_LOCK = 2; // 0x2
+    field public static final int SIGNAL_NO_SIGNAL = 1; // 0x1
+  }
+
+  public interface ScanCallback {
+    method public void onAnalogSifStandard(int);
+    method public void onAtsc3PlpInfos(@NonNull android.media.tv.tuner.frontend.Atsc3PlpInfo[]);
+    method public void onDvbsStandard(int);
+    method public void onDvbtStandard(int);
+    method public void onFrequenciesReport(@NonNull int[]);
+    method public void onGroupIds(@NonNull int[]);
+    method public void onHierarchy(int);
+    method public void onInputStreamIds(@NonNull int[]);
+    method public void onLocked();
+    method public void onPlpIds(@NonNull int[]);
+    method public void onProgress(@IntRange(from=0, to=100) int);
+    method public void onScanStopped();
+    method public void onSignalType(int);
+    method public void onSymbolRates(@NonNull int[]);
+  }
+
 }
 
 package android.metrics {
@@ -4974,6 +5465,8 @@
   }
 
   public abstract class NetworkAgent {
+    ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
+    method @Nullable public android.net.Network getNetwork();
     method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
     method public void onAutomaticReconnectDisabled();
     method public void onBandwidthUpdateRequested();
@@ -4984,21 +5477,30 @@
     method public void onStartSocketKeepalive(int, int, @NonNull android.net.KeepalivePacketData);
     method public void onStopSocketKeepalive(int);
     method public void onValidationStatus(int, @Nullable String);
+    method @NonNull public android.net.Network register();
     method public void sendLinkProperties(@NonNull android.net.LinkProperties);
     method public void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
     method public void sendNetworkScore(int);
     method public void sendSocketKeepaliveEvent(int, int);
+    method public void setConnected();
+    method @Deprecated public void setLegacyExtraInfo(@Nullable String);
+    method @Deprecated public void setLegacySubtype(int, @NonNull String);
+    method public void unregister();
     field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
     field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
-    field @NonNull public final android.net.Network network;
     field public final int providerId;
   }
 
   public final class NetworkAgentConfig implements android.os.Parcelable {
     method public int describeContents();
+    method public int getLegacyType();
+    method @NonNull public String getLegacyTypeName();
     method @Nullable public String getSubscriberId();
+    method public boolean isExplicitlySelected();
     method public boolean isNat64DetectionEnabled();
+    method public boolean isPartialConnectivityAcceptable();
     method public boolean isProvisioningNotificationEnabled();
+    method public boolean isUnvalidatedConnectivityAcceptable();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
   }
@@ -5008,7 +5510,12 @@
     method @NonNull public android.net.NetworkAgentConfig build();
     method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection();
     method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification();
+    method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
     method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
@@ -5325,9 +5832,11 @@
   }
 
   public abstract class ChildSessionParams {
+    method public long getHardLifetime();
     method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getLocalTrafficSelectors();
     method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getRemoteTrafficSelectors();
     method @NonNull public java.util.List<android.net.ipsec.ike.ChildSaProposal> getSaProposals();
+    method public long getSoftLifetime();
   }
 
   public class IkeFqdnIdentification extends android.net.ipsec.ike.IkeIdentification {
@@ -5396,12 +5905,14 @@
   }
 
   public final class IkeSessionParams {
+    method public long getHardLifetime();
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig getLocalAuthConfig();
     method @NonNull public android.net.ipsec.ike.IkeIdentification getLocalIdentification();
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig getRemoteAuthConfig();
     method @NonNull public android.net.ipsec.ike.IkeIdentification getRemoteIdentification();
     method @NonNull public java.util.List<android.net.ipsec.ike.IkeSaProposal> getSaProposals();
     method @NonNull public java.net.InetAddress getServerAddress();
+    method public long getSoftLifetime();
     method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket getUdpEncapsulationSocket();
   }
 
@@ -5413,6 +5924,7 @@
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthDigitalSignature(@Nullable java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.util.List<java.security.cert.X509Certificate>, @NonNull java.security.PrivateKey);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthEap(@Nullable java.security.cert.X509Certificate, @NonNull android.net.eap.EapSessionConfig);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthPsk(@NonNull byte[]);
+    method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLifetime(long, long);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLocalIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setRemoteIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setServerAddress(@NonNull java.net.InetAddress);
@@ -5483,6 +5995,7 @@
     method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
     method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
     method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams build();
+    method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder setLifetime(long, long);
   }
 
   public final class TunnelModeChildSessionParams extends android.net.ipsec.ike.ChildSessionParams {
@@ -5500,6 +6013,7 @@
     method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
     method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
     method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams build();
+    method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder setLifetime(long, long);
   }
 
   public static interface TunnelModeChildSessionParams.ConfigRequest {
@@ -6002,29 +6516,18 @@
   }
 
   public final class SoftApConfiguration implements android.os.Parcelable {
-    method public int describeContents();
     method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList();
     method public int getBand();
     method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
-    method @Nullable public android.net.MacAddress getBssid();
     method public int getChannel();
     method public int getMaxNumberOfClients();
-    method @Nullable public String getPassphrase();
-    method public int getSecurityType();
     method public int getShutdownTimeoutMillis();
-    method @Nullable public String getSsid();
     method public boolean isClientControlByUserEnabled();
-    method public boolean isHiddenSsid();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
     field public static final int BAND_2GHZ = 1; // 0x1
     field public static final int BAND_5GHZ = 2; // 0x2
     field public static final int BAND_6GHZ = 4; // 0x4
     field public static final int BAND_ANY = 7; // 0x7
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
-    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
-    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
-    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
-    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
   }
 
   public static final class SoftApConfiguration.Builder {
@@ -6205,6 +6708,7 @@
     method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
     method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
     method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
@@ -6222,7 +6726,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
     method public int getVerboseLoggingLevel();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
     method public boolean isApMacRandomizationSupported();
@@ -6249,6 +6753,7 @@
     method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
     method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
     method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
@@ -6338,6 +6843,11 @@
     method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
   }
 
+  public static interface WifiManager.ScoreChangeCallback {
+    method public void onStatusChange(int, boolean);
+    method public void onTriggerUpdateOfWifiUsabilityStats(int);
+  }
+
   public static interface WifiManager.SoftApCallback {
     method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
     method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
@@ -6354,6 +6864,12 @@
     field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
   }
 
+  public static interface WifiManager.WifiConnectedNetworkScorer {
+    method public void setScoreChangeCallback(@NonNull android.net.wifi.WifiManager.ScoreChangeCallback);
+    method public void start(int);
+    method public void stop(int);
+  }
+
   public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
     ctor public WifiNetworkConnectionStatistics(int, int);
     ctor public WifiNetworkConnectionStatistics();
@@ -6369,6 +6885,11 @@
     method public boolean satisfiedBy(android.net.NetworkSpecifier);
   }
 
+  public final class WifiNetworkSuggestion implements android.os.Parcelable {
+    method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfiguration();
+    method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
+  }
+
   public static final class WifiNetworkSuggestion.Builder {
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
   }
@@ -6396,17 +6917,17 @@
     method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
     method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
     method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
     method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void registerScanListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiScanner.ScanListener);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setScanningEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
     method @Deprecated public void startTrackingBssids(android.net.wifi.WifiScanner.BssidInfo[], int, android.net.wifi.WifiScanner.BssidListener);
     method @Deprecated public void startTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopScan(android.net.wifi.WifiScanner.ScanListener);
     method @Deprecated public void stopTrackingBssids(android.net.wifi.WifiScanner.BssidListener);
     method @Deprecated public void stopTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
@@ -6489,7 +7010,7 @@
 
   public static interface WifiScanner.ScanListener extends android.net.wifi.WifiScanner.ActionListener {
     method public void onFullResult(android.net.wifi.ScanResult);
-    method public void onPeriodChanged(int);
+    method @Deprecated public void onPeriodChanged(int);
     method public void onResults(android.net.wifi.WifiScanner.ScanData[]);
   }
 
@@ -6500,12 +7021,12 @@
     field @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public final java.util.List<android.net.wifi.WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks;
     field public boolean hideFromAppOps;
     field public boolean ignoreLocationSettings;
-    field public int maxPeriodInMs;
-    field public int maxScansToCache;
-    field public int numBssidsPerScan;
-    field public int periodInMs;
-    field public int reportEvents;
-    field public int stepCount;
+    field @Deprecated public int maxPeriodInMs;
+    field @Deprecated public int maxScansToCache;
+    field @Deprecated public int numBssidsPerScan;
+    field @Deprecated public int periodInMs;
+    field @Deprecated public int reportEvents;
+    field @Deprecated public int stepCount;
     field @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public int type;
   }
 
@@ -6730,6 +7251,21 @@
 
 package android.net.wifi.wificond {
 
+  public final class DeviceWiphyCapabilities implements android.os.Parcelable {
+    ctor public DeviceWiphyCapabilities();
+    method public int describeContents();
+    method public int getMaxNumberRxSpatialStreams();
+    method public int getMaxNumberTxSpatialStreams();
+    method public boolean isChannelWidthSupported(int);
+    method public boolean isWifiStandardSupported(int);
+    method public void setChannelWidthSupported(int, boolean);
+    method public void setMaxNumberRxSpatialStreams(int);
+    method public void setMaxNumberTxSpatialStreams(int);
+    method public void setWifiStandardSupport(int, boolean);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.DeviceWiphyCapabilities> CREATOR;
+  }
+
   public final class NativeScanResult implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public byte[] getBssid();
@@ -6794,6 +7330,7 @@
     method public void abortScan(@NonNull String);
     method public void enableVerboseLogging(boolean);
     method @NonNull public int[] getChannelsMhzForBand(int);
+    method @Nullable public android.net.wifi.wificond.DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String);
     method @NonNull public java.util.List<android.net.wifi.wificond.NativeScanResult> getScanResults(@NonNull String, int);
     method @Nullable public android.net.wifi.wificond.WifiCondManager.TxPacketCounters getTxPacketCounters(@NonNull String);
     method public boolean initialize(@NonNull Runnable);
@@ -7352,6 +7889,11 @@
     field public static final int TUPLE_VALUE_TYPE = 7; // 0x7
   }
 
+  public class SystemConfigManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+  }
+
   public class SystemProperties {
     method @NonNull public static String get(@NonNull String);
     method @NonNull public static String get(@NonNull String, @Nullable String);
@@ -7481,6 +8023,7 @@
 
   public class UserManager {
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void clearSeedAccountData();
+    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle createProfile(@NonNull String, @NonNull String, @Nullable String[]) throws android.os.UserManager.UserOperationException;
     method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.UserHandle getProfileParent(@NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountName();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions();
@@ -7488,22 +8031,26 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean);
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserHandle> getUserHandles(boolean);
     method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public android.graphics.Bitmap getUserIcon();
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public java.util.List<android.os.UserHandle> getUserProfiles(boolean);
     method @Deprecated @android.os.UserManager.UserRestrictionSource @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public int getUserRestrictionSource(String, android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(String, android.os.UserHandle);
     method @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public int getUserSwitchability();
-    method public boolean hasRestrictedProfiles();
+    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean hasRestrictedProfiles();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean hasUserRestrictionForUser(@NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isAdminUser();
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isGuestUser();
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isManagedProfile(int);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isPrimaryUser();
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isGuestUser();
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isManagedProfile(int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isPrimaryUser();
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isProfile();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile();
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile(@NonNull android.os.UserHandle);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isRestrictedProfile(@NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isSameProfileGroup(@NonNull android.os.UserHandle, @NonNull android.os.UserHandle);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public boolean isUserNameSet();
-    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public boolean isUserUnlockingOrUnlocked(@NonNull android.os.UserHandle);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(@NonNull android.os.UserHandle);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isUserOfType(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isUserOfType(@NonNull android.os.UserHandle, @NonNull String);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isUserUnlockingOrUnlocked(@NonNull android.os.UserHandle);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean removeUser(@NonNull android.os.UserHandle);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap) throws android.os.UserManager.UserOperationException;
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
     field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
     field @Deprecated public static final String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
@@ -7516,6 +8063,10 @@
     field public static final int SWITCHABILITY_STATUS_SYSTEM_USER_LOCKED = 4; // 0x4
     field public static final int SWITCHABILITY_STATUS_USER_IN_CALL = 1; // 0x1
     field public static final int SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED = 2; // 0x2
+    field public static final String USER_TYPE_FULL_SECONDARY = "android.os.usertype.full.SECONDARY";
+    field public static final String USER_TYPE_FULL_SYSTEM = "android.os.usertype.full.SYSTEM";
+    field public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED";
+    field public static final String USER_TYPE_SYSTEM_HEADLESS = "android.os.usertype.system.HEADLESS";
   }
 
   public static final class UserManager.EnforcingUser implements android.os.Parcelable {
@@ -8275,6 +8826,7 @@
   public static final class Telephony.SimInfo {
     field public static final String ACCESS_RULES = "access_rules";
     field public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = "access_rules_from_carrier_configs";
+    field public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types";
     field public static final String CARD_ID = "card_id";
     field public static final String CARRIER_ID = "carrier_id";
     field public static final String CARRIER_NAME = "carrier_name";
@@ -8784,6 +9336,7 @@
 
   public abstract class EuiccService extends android.app.Service {
     ctor public EuiccService();
+    method public void dump(@NonNull java.io.PrintWriter);
     method @CallSuper public android.os.IBinder onBind(android.content.Intent);
     method public abstract int onDeleteSubscription(int, String);
     method public android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean, @Nullable android.os.Bundle);
@@ -9486,8 +10039,6 @@
 
   public final class AccessNetworkConstants {
     field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
-    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
-    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
   }
 
   public final class BarringInfo implements android.os.Parcelable {
@@ -10132,37 +10683,18 @@
   }
 
   public final class NetworkRegistrationInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAccessNetworkTechnology();
-    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
-    method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
-    method public int getDomain();
-    method public int getNrState();
     method public int getRegistrationState();
     method public int getRejectCause();
     method public int getRoamingType();
-    method public int getTransportType();
     method public boolean isEmergencyEnabled();
-    method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
-    field public static final int DOMAIN_CS = 1; // 0x1
-    field public static final int DOMAIN_CS_PS = 3; // 0x3
-    field public static final int DOMAIN_PS = 2; // 0x2
-    field public static final int DOMAIN_UNKNOWN = 0; // 0x0
     field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
     field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
     field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
     field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
-    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
-    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
-    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
-    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
-    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
   }
 
   public static final class NetworkRegistrationInfo.Builder {
@@ -10246,6 +10778,19 @@
     field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
   }
 
+  public final class PinResult implements android.os.Parcelable {
+    ctor public PinResult(int, int);
+    method public int describeContents();
+    method public int getAttemptsRemaining();
+    method @NonNull public static android.telephony.PinResult getDefaultFailedResult();
+    method public int getType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PinResult> CREATOR;
+    field public static final int PIN_RESULT_TYPE_FAILURE = 2; // 0x2
+    field public static final int PIN_RESULT_TYPE_INCORRECT = 1; // 0x1
+    field public static final int PIN_RESULT_TYPE_SUCCESS = 0; // 0x0
+  }
+
   public final class PreciseCallState implements android.os.Parcelable {
     ctor public PreciseCallState(int, int, int, int, int);
     method public int describeContents();
@@ -10380,7 +10925,6 @@
     method public int getDataRegistrationState();
     method public boolean getDataRoamingFromRegistration();
     method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
-    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
     method public int getNrFrequencyRange();
@@ -10526,7 +11070,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc();
-    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int);
     field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3
@@ -10615,6 +11159,7 @@
   public class TelephonyManager {
     method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting);
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int changeIccLockPassword(@NonNull String, @NonNull String);
     method public int checkCarrierPrivilegesForPackage(String);
     method public int checkCarrierPrivilegesForPackageAnyPhone(String);
     method public void dial(String);
@@ -10624,6 +11169,7 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -10677,10 +11223,13 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
     method public boolean isCurrentSimOperator(@NonNull String, int, @Nullable String);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataAllowedInVoiceCall();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionEnabled();
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isGlobalModeEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isManualNetworkSelectionAllowed();
@@ -10706,14 +11255,17 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
     method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaRoamingMode(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaSubscriptionMode(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setDataAllowedDuringVoiceCall(boolean);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIccLockEnabled(boolean, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPolicyDataEnabled(boolean);
@@ -10727,9 +11279,11 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPinReportPinResult(@NonNull String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPukReportPinResult(@NonNull String, @NonNull String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
     method public void updateServiceLocation();
@@ -10750,6 +11304,9 @@
     field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
     field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
     field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
+    field public static final int CARD_POWER_DOWN = 0; // 0x0
+    field public static final int CARD_POWER_UP = 1; // 0x1
+    field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
@@ -10757,6 +11314,7 @@
     field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
     field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
     field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
+    field public static final int CHANGE_ICC_LOCK_SUCCESS = 2147483647; // 0x7fffffff
     field public static final int DEFAULT_PREFERRED_NETWORK_MODE = 0; // 0x0
     field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
     field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
@@ -10902,6 +11460,23 @@
 
 package android.telephony.data {
 
+  public class ApnSetting implements android.os.Parcelable {
+    method @NonNull public static String getApnTypesStringFromBitmask(int);
+    field public static final String TYPE_ALL_STRING = "*";
+    field public static final String TYPE_CBS_STRING = "cbs";
+    field public static final String TYPE_DEFAULT_STRING = "default";
+    field public static final String TYPE_DUN_STRING = "dun";
+    field public static final String TYPE_EMERGENCY_STRING = "emergency";
+    field public static final String TYPE_FOTA_STRING = "fota";
+    field public static final String TYPE_HIPRI_STRING = "hipri";
+    field public static final String TYPE_IA_STRING = "ia";
+    field public static final String TYPE_IMS_STRING = "ims";
+    field public static final String TYPE_MCX_STRING = "mcx";
+    field public static final String TYPE_MMS_STRING = "mms";
+    field public static final String TYPE_SUPL_STRING = "supl";
+    field public static final String TYPE_XCAP_STRING = "xcap";
+  }
+
   public final class DataCallResponse implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -11214,6 +11789,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @Nullable public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
     method public static int getVideoStateFromCallType(int);
@@ -11352,10 +11928,6 @@
     ctor public ImsException(@Nullable String);
     ctor public ImsException(@Nullable String, int);
     ctor public ImsException(@Nullable String, int, @Nullable Throwable);
-    method public int getCode();
-    field public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; // 0x1
-    field public static final int CODE_ERROR_UNSPECIFIED = 0; // 0x0
-    field public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2; // 0x2
   }
 
   public final class ImsExternalCallState implements android.os.Parcelable {
@@ -11381,23 +11953,13 @@
   }
 
   public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
-    method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAdvancedCallingSettingEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isTtyOverVolteEnabled();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiRoamingSettingEnabled();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiSettingEnabled();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVtSettingEnabled();
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
@@ -11407,16 +11969,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterMmTelCapabilityCallback(@NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback);
-    field public static final int WIFI_MODE_CELLULAR_PREFERRED = 1; // 0x1
-    field public static final int WIFI_MODE_WIFI_ONLY = 0; // 0x0
-    field public static final int WIFI_MODE_WIFI_PREFERRED = 2; // 0x2
-  }
-
-  public static class ImsMmTelManager.CapabilityCallback {
-    ctor public ImsMmTelManager.CapabilityCallback();
-    method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
   }
 
   @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
@@ -11716,6 +12268,9 @@
     method public boolean isCapable(int);
     method public boolean isCapable(@NonNull String);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CAPABILITY_CALL_COMPOSER = 4194304; // 0x400000
+    field public static final int CAPABILITY_CHAT_BOT = 67108864; // 0x4000000
+    field public static final int CAPABILITY_CHAT_BOT_ROLE = 134217728; // 0x8000000
     field public static final int CAPABILITY_CHAT_SESSION = 2; // 0x2
     field public static final int CAPABILITY_CHAT_SESSION_STORE_FORWARD = 4; // 0x4
     field public static final int CAPABILITY_CHAT_STANDALONE = 1; // 0x1
@@ -11732,9 +12287,13 @@
     field public static final int CAPABILITY_IMAGE_SHARE = 256; // 0x100
     field public static final int CAPABILITY_IP_VIDEO_CALL = 16384; // 0x4000
     field public static final int CAPABILITY_IP_VOICE_CALL = 8192; // 0x2000
+    field public static final int CAPABILITY_PLUG_IN = 268435456; // 0x10000000
+    field public static final int CAPABILITY_POST_CALL = 8388608; // 0x800000
     field public static final int CAPABILITY_RCS_VIDEO_CALL = 1048576; // 0x100000
     field public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = 2097152; // 0x200000
     field public static final int CAPABILITY_RCS_VOICE_CALL = 524288; // 0x80000
+    field public static final int CAPABILITY_SHARED_MAP = 16777216; // 0x1000000
+    field public static final int CAPABILITY_SHARED_SKETCH = 33554432; // 0x2000000
     field public static final int CAPABILITY_SOCIAL_PRESENCE = 2048; // 0x800
     field public static final int CAPABILITY_VIDEO_SHARE = 1024; // 0x400
     field public static final int CAPABILITY_VIDEO_SHARE_DURING_CS_CALL = 512; // 0x200
@@ -11749,24 +12308,6 @@
     method @NonNull public android.telephony.ims.RcsContactUceCapability build();
   }
 
-  public interface RegistrationManager {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
-    field public static final int REGISTRATION_STATE_NOT_REGISTERED = 0; // 0x0
-    field public static final int REGISTRATION_STATE_REGISTERED = 2; // 0x2
-    field public static final int REGISTRATION_STATE_REGISTERING = 1; // 0x1
-  }
-
-  public static class RegistrationManager.RegistrationCallback {
-    ctor public RegistrationManager.RegistrationCallback();
-    method public void onRegistered(int);
-    method public void onRegistering(int);
-    method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
-    method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
-  }
-
 }
 
 package android.telephony.ims.feature {
@@ -11790,6 +12331,7 @@
   public abstract class ImsFeature {
     ctor public ImsFeature();
     method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public int getFeatureState();
     method public final int getSlotIndex();
     method public abstract void onFeatureReady();
     method public abstract void onFeatureRemoved();
@@ -11828,7 +12370,7 @@
     method public void onFeatureReady();
     method public void onFeatureRemoved();
     method public boolean queryCapabilityConfiguration(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
-    method public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
+    method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
     method public void setUiTtyMode(int, @Nullable android.os.Message);
     method @android.telephony.ims.feature.MmTelFeature.ProcessCallResult public int shouldProcessCall(@NonNull String[]);
     field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
@@ -11844,10 +12386,6 @@
     method public final void addCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
     method public final boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
     method public final void removeCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
-    field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8
-    field public static final int CAPABILITY_TYPE_UT = 4; // 0x4
-    field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2
-    field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1
   }
 
   @IntDef(flag=true, value={android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MmTelFeature.MmTelCapabilities.MmTelCapability {
@@ -12037,6 +12575,17 @@
     method public int updateClir(int);
     method public int updateColp(boolean);
     method public int updateColr(int);
+    field public static final int CALL_BARRING_ALL = 7; // 0x7
+    field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1
+    field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2
+    field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6
+    field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9
+    field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8
+    field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3
+    field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4
+    field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa
+    field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5
+    field public static final int INVALID_RESULT = -1; // 0xffffffff
   }
 
 }
diff --git a/api/test-current.txt b/api/test-current.txt
index 28119e3..d4b799d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -70,12 +70,15 @@
     method public long getTotalRam();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
     method public static boolean isHighEndGfx();
+    method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void killProcessesWhenImperceptible(@NonNull int[], @NonNull String);
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public static void resumeAppSwitches() throws android.os.RemoteException;
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
     method @RequiresPermission("android.permission.MANAGE_USERS") public boolean switchUser(@NonNull android.os.UserHandle);
-    field public static final int PROCESS_CAPABILITY_ALL = 1; // 0x1
+    field public static final int PROCESS_CAPABILITY_ALL = 7; // 0x7
+    field public static final int PROCESS_CAPABILITY_FOREGROUND_CAMERA = 2; // 0x2
     field public static final int PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1; // 0x1
+    field public static final int PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 4; // 0x4
     field public static final int PROCESS_CAPABILITY_NONE = 0; // 0x0
   }
 
@@ -1119,6 +1122,7 @@
     method @RequiresPermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE) public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents();
     method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration();
     method public android.graphics.Point getStableDisplaySize();
+    method public boolean isMinimalPostProcessingRequested(int);
     method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
   }
 
@@ -2179,6 +2183,11 @@
     method public void log(android.os.StrictMode.ViolationInfo);
   }
 
+  public class SystemConfigManager {
+    method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps();
+    method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+  }
+
   public class SystemProperties {
     method @NonNull public static String get(@NonNull String);
     method @NonNull public static String get(@NonNull String, @Nullable String);
@@ -3141,8 +3150,6 @@
 
   public final class AccessNetworkConstants {
     field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
-    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
-    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
   }
 
   public final class BarringInfo implements android.os.Parcelable {
@@ -3218,36 +3225,18 @@
   }
 
   public final class NetworkRegistrationInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAccessNetworkTechnology();
-    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
-    method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
-    method public int getDomain();
     method public int getRegistrationState();
     method public int getRejectCause();
     method public int getRoamingType();
-    method public int getTransportType();
     method public boolean isEmergencyEnabled();
-    method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
-    field public static final int DOMAIN_CS = 1; // 0x1
-    field public static final int DOMAIN_CS_PS = 3; // 0x3
-    field public static final int DOMAIN_PS = 2; // 0x2
-    field public static final int DOMAIN_UNKNOWN = 0; // 0x0
     field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
     field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
     field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
     field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
-    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
-    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
-    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
-    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
-    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
   }
 
   public static final class NetworkRegistrationInfo.Builder {
@@ -3296,7 +3285,7 @@
 
   public final class SmsManager {
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
-    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
     field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
     field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
     field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
@@ -3393,6 +3382,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @Nullable public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
     method public static int getVideoStateFromCallType(int);
@@ -3446,6 +3436,7 @@
     field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
     field public static final String EXTRA_EMERGENCY_CALL = "e_call";
     field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+    field public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
     field public static final String EXTRA_OI = "oi";
     field public static final String EXTRA_OIR = "oir";
     field public static final String EXTRA_REMOTE_URI = "remote_uri";
@@ -3531,10 +3522,6 @@
     ctor public ImsException(@Nullable String);
     ctor public ImsException(@Nullable String, int);
     ctor public ImsException(@Nullable String, int, @Nullable Throwable);
-    method public int getCode();
-    field public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; // 0x1
-    field public static final int CODE_ERROR_UNSPECIFIED = 0; // 0x0
-    field public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2; // 0x2
   }
 
   public final class ImsExternalCallState implements android.os.Parcelable {
@@ -3560,23 +3547,13 @@
   }
 
   public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
-    method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getVoWiFiModeSetting();
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getVoWiFiRoamingModeSetting();
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isAdvancedCallingSettingEnabled();
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isAvailable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void isSupported(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isTtyOverVolteEnabled();
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isVoWiFiRoamingSettingEnabled();
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isVoWiFiSettingEnabled();
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isVtSettingEnabled();
     method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
@@ -3586,16 +3563,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
     method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterMmTelCapabilityCallback(@NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback);
-    field public static final int WIFI_MODE_CELLULAR_PREFERRED = 1; // 0x1
-    field public static final int WIFI_MODE_WIFI_ONLY = 0; // 0x0
-    field public static final int WIFI_MODE_WIFI_PREFERRED = 2; // 0x2
-  }
-
-  public static class ImsMmTelManager.CapabilityCallback {
-    ctor public ImsMmTelManager.CapabilityCallback();
-    method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
   }
 
   @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
@@ -3883,24 +3850,6 @@
     method public void onProvisioningStringChanged(int, @NonNull String);
   }
 
-  public interface RegistrationManager {
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
-    field public static final int REGISTRATION_STATE_NOT_REGISTERED = 0; // 0x0
-    field public static final int REGISTRATION_STATE_REGISTERED = 2; // 0x2
-    field public static final int REGISTRATION_STATE_REGISTERING = 1; // 0x1
-  }
-
-  public static class RegistrationManager.RegistrationCallback {
-    ctor public RegistrationManager.RegistrationCallback();
-    method public void onRegistered(int);
-    method public void onRegistering(int);
-    method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
-    method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
-  }
-
 }
 
 package android.telephony.ims.feature {
@@ -3924,6 +3873,7 @@
   public abstract class ImsFeature {
     ctor public ImsFeature();
     method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public int getFeatureState();
     method public final int getSlotIndex();
     method public abstract void onFeatureReady();
     method public abstract void onFeatureRemoved();
@@ -3962,7 +3912,7 @@
     method public void onFeatureReady();
     method public void onFeatureRemoved();
     method public boolean queryCapabilityConfiguration(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
-    method public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
+    method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
     method public void setUiTtyMode(int, @Nullable android.os.Message);
     method @android.telephony.ims.feature.MmTelFeature.ProcessCallResult public int shouldProcessCall(@NonNull String[]);
     field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
@@ -3978,10 +3928,6 @@
     method public final void addCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
     method public final boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
     method public final void removeCapabilities(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int);
-    field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8
-    field public static final int CAPABILITY_TYPE_UT = 4; // 0x4
-    field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2
-    field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1
   }
 
   @IntDef(flag=true, value={android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT, android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MmTelFeature.MmTelCapabilities.MmTelCapability {
@@ -4171,6 +4117,17 @@
     method public int updateClir(int);
     method public int updateColp(boolean);
     method public int updateColr(int);
+    field public static final int CALL_BARRING_ALL = 7; // 0x7
+    field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1
+    field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2
+    field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6
+    field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9
+    field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8
+    field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3
+    field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4
+    field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa
+    field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5
+    field public static final int INVALID_RESULT = -1; // 0xffffffff
   }
 
 }
@@ -4501,7 +4458,7 @@
     field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
     field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40
     field public CharSequence accessibilityTitle;
-    field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=0x1, equals=0x1, name="FAKE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x2, equals=0x2, name="FORCE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x4, equals=0x4, name="WANTS_OFFSET_NOTIFICATIONS"), @android.view.ViewDebug.FlagToString(mask=0x10, equals=0x10, name="SHOW_FOR_ALL_USERS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, equals=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, name="NO_MOVE_ANIMATION"), @android.view.ViewDebug.FlagToString(mask=0x80, equals=0x80, name="COMPATIBLE_WINDOW"), @android.view.ViewDebug.FlagToString(mask=0x100, equals=0x100, name="SYSTEM_ERROR"), @android.view.ViewDebug.FlagToString(mask=0x400, equals=0x400, name="KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=0x800, equals=0x800, name="DISABLE_WALLPAPER_TOUCH_EVENTS"), @android.view.ViewDebug.FlagToString(mask=0x1000, equals=0x1000, name="FORCE_STATUS_BAR_VISIBLE_TRANSPARENT"), @android.view.ViewDebug.FlagToString(mask=0x2000, equals=0x2000, name="PRESERVE_GEOMETRY"), @android.view.ViewDebug.FlagToString(mask=0x4000, equals=0x4000, name="FORCE_DECOR_VIEW_VISIBILITY"), @android.view.ViewDebug.FlagToString(mask=0x8000, equals=0x8000, name="WILL_NOT_REPLACE_ON_RELAUNCH"), @android.view.ViewDebug.FlagToString(mask=0x10000, equals=0x10000, name="LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"), @android.view.ViewDebug.FlagToString(mask=0x20000, equals=0x20000, name="FORCE_DRAW_STATUS_BAR_BACKGROUND"), @android.view.ViewDebug.FlagToString(mask=0x40000, equals=0x40000, name="SUSTAINED_PERFORMANCE_MODE"), @android.view.ViewDebug.FlagToString(mask=0x80000, equals=0x80000, name="HIDE_NON_SYSTEM_OVERLAY_WINDOWS"), @android.view.ViewDebug.FlagToString(mask=0x100000, equals=0x100000, name="IS_ROUNDED_CORNERS_OVERLAY"), @android.view.ViewDebug.FlagToString(mask=0x400000, equals=0x400000, name="IS_SCREEN_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x800000, equals=0x800000, name="STATUS_FORCE_SHOW_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=0x1000000, equals=0x1000000, name="COLOR_SPACE_AGNOSTIC"), @android.view.ViewDebug.FlagToString(mask=0x4000000, equals=0x4000000, name="FIT_INSETS_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x8000000, equals=0x8000000, name="ONLY_DRAW_BOTTOM_BAR_BACKGROUND")}) public int privateFlags;
+    field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=0x1, equals=0x1, name="FAKE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x2, equals=0x2, name="FORCE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x4, equals=0x4, name="WANTS_OFFSET_NOTIFICATIONS"), @android.view.ViewDebug.FlagToString(mask=0x10, equals=0x10, name="SHOW_FOR_ALL_USERS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, equals=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, name="NO_MOVE_ANIMATION"), @android.view.ViewDebug.FlagToString(mask=0x80, equals=0x80, name="COMPATIBLE_WINDOW"), @android.view.ViewDebug.FlagToString(mask=0x100, equals=0x100, name="SYSTEM_ERROR"), @android.view.ViewDebug.FlagToString(mask=0x800, equals=0x800, name="DISABLE_WALLPAPER_TOUCH_EVENTS"), @android.view.ViewDebug.FlagToString(mask=0x1000, equals=0x1000, name="FORCE_STATUS_BAR_VISIBLE"), @android.view.ViewDebug.FlagToString(mask=0x2000, equals=0x2000, name="PRESERVE_GEOMETRY"), @android.view.ViewDebug.FlagToString(mask=0x4000, equals=0x4000, name="FORCE_DECOR_VIEW_VISIBILITY"), @android.view.ViewDebug.FlagToString(mask=0x8000, equals=0x8000, name="WILL_NOT_REPLACE_ON_RELAUNCH"), @android.view.ViewDebug.FlagToString(mask=0x10000, equals=0x10000, name="LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"), @android.view.ViewDebug.FlagToString(mask=0x20000, equals=0x20000, name="FORCE_DRAW_STATUS_BAR_BACKGROUND"), @android.view.ViewDebug.FlagToString(mask=0x40000, equals=0x40000, name="SUSTAINED_PERFORMANCE_MODE"), @android.view.ViewDebug.FlagToString(mask=0x80000, equals=0x80000, name="HIDE_NON_SYSTEM_OVERLAY_WINDOWS"), @android.view.ViewDebug.FlagToString(mask=0x100000, equals=0x100000, name="IS_ROUNDED_CORNERS_OVERLAY"), @android.view.ViewDebug.FlagToString(mask=0x400000, equals=0x400000, name="IS_SCREEN_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x800000, equals=0x800000, name="STATUS_FORCE_SHOW_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=0x1000000, equals=0x1000000, name="COLOR_SPACE_AGNOSTIC"), @android.view.ViewDebug.FlagToString(mask=0x4000000, equals=0x4000000, name="APPEARANCE_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x8000000, equals=0x8000000, name="BEHAVIOR_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x10000000, equals=0x10000000, name="FIT_INSETS_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x20000000, equals=0x20000000, name="ONLY_DRAW_BOTTOM_BAR_BACKGROUND")}) public int privateFlags;
   }
 
 }
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8fac31a..2537eda 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -100,6 +100,7 @@
 static const int TEXT_CENTER_VALUE = INT_MAX;
 static const int TEXT_MISSING_VALUE = INT_MIN;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
+static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
 static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
 static constexpr size_t TEXT_POS_LEN_MAX = 16;
 
@@ -291,10 +292,10 @@
 
     // this guest property specifies multi-display IDs to show the boot animation
     // multiple ids can be set with comma (,) as separator, for example:
-    // setprop boot.animation.displays 19260422155234049,19261083906282754
+    // setprop persist.boot.animation.displays 19260422155234049,19261083906282754
     Vector<uint64_t> physicalDisplayIds;
     char displayValue[PROPERTY_VALUE_MAX] = "";
-    property_get("boot.animation.displays", displayValue, "");
+    property_get(DISPLAYS_PROP_NAME, displayValue, "");
     bool isValid = displayValue[0] != '\0';
     if (isValid) {
         char *p = displayValue;
@@ -306,7 +307,7 @@
             p ++;
         }
         if (!isValid)
-            SLOGE("Invalid syntax for the value of system prop: boot.animation.displays");
+            SLOGE("Invalid syntax for the value of system prop: %s", DISPLAYS_PROP_NAME);
     }
     if (isValid) {
         std::istringstream stream(displayValue);
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 1c6867c3..6eafbd8 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -73,7 +73,6 @@
         "src/external/puller_util.cpp",
         "src/external/ResourceHealthManagerPuller.cpp",
         "src/external/StatsCallbackPuller.cpp",
-        "src/external/StatsCallbackPullerDeprecated.cpp",
         "src/external/StatsCompanionServicePuller.cpp",
         "src/external/StatsPuller.cpp",
         "src/external/StatsPullerManager.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ada2f2d..c1a8d69 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1265,16 +1265,6 @@
     return Status::ok();
 }
 
-Status StatsService::registerPullerCallback(int32_t atomTag,
-        const sp<android::os::IStatsPullerCallback>& pullerCallback,
-        const String16& packageName) {
-    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
-
-    VLOG("StatsService::registerPullerCallback called.");
-    mPullerManager->RegisterPullerCallback(atomTag, pullerCallback);
-    return Status::ok();
-}
-
 Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
                                     int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
                                     const sp<android::os::IPullAtomCallback>& pullerCallback) {
@@ -1297,14 +1287,6 @@
     return Status::ok();
 }
 
-Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& packageName) {
-    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
-
-    VLOG("StatsService::unregisterPullerCallback called.");
-    mPullerManager->UnregisterPullerCallback(atomTag);
-    return Status::ok();
-}
-
 Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
     ENFORCE_UID(AID_SYSTEM);
     VLOG("StatsService::unregisterPullAtomCallback called.");
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 7990e5e..f2079d9 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -171,14 +171,6 @@
     virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
 
     /**
-     * Binder call to register a callback function for a vendor pulled atom.
-     * Note: this atom must NOT have uid as a field.
-     */
-    virtual Status registerPullerCallback(int32_t atomTag,
-        const sp<android::os::IStatsPullerCallback>& pullerCallback,
-        const String16& packageName) override;
-
-    /**
      * Binder call to register a callback function for a pulled atom.
      */
     virtual Status registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
@@ -193,11 +185,6 @@
             const sp<android::os::IPullAtomCallback>& pullerCallback) override;
 
     /**
-     * Binder call to unregister any existing callback function for a vendor pulled atom.
-     */
-    virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
-
-    /**
      * Binder call to unregister any existing callback for the given uid and atom.
      */
     virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override;
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
deleted file mode 100644
index 4f88a91..0000000
--- a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsCallbackPullerDeprecated.h"
-
-#include <android/os/IStatsPullerCallback.h>
-
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-
-using namespace android::binder;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsCallbackPullerDeprecated::StatsCallbackPullerDeprecated(
-        int tagId, const sp<IStatsPullerCallback>& callback)
-    : StatsPuller(tagId), mCallback(callback) {
-    VLOG("StatsCallbackPuller created for tag %d", tagId);
-}
-
-bool StatsCallbackPullerDeprecated::PullInternal(vector<shared_ptr<LogEvent>>* data) {
-    VLOG("StatsCallbackPuller called for tag %d", mTagId)
-    if (mCallback == nullptr) {
-        ALOGW("No callback registered");
-        return false;
-    }
-    int64_t wallClockTimeNs = getWallClockNs();
-    int64_t elapsedTimeNs = getElapsedRealtimeNs();
-    vector<StatsLogEventWrapper> returned_value;
-    Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
-    if (!status.isOk()) {
-        ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
-        return false;
-    }
-    data->clear();
-    for (const StatsLogEventWrapper& it : returned_value) {
-        LogEvent::createLogEvents(it, *data);
-    }
-    VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
deleted file mode 100644
index 0289029..0000000
--- a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/os/IStatsPullerCallback.h>
-#include <utils/String16.h>
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCallbackPullerDeprecated : public StatsPuller {
-public:
-    explicit StatsCallbackPullerDeprecated(int tagId, const sp<IStatsPullerCallback>& callback);
-
-private:
-    bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
-    const sp<IStatsPullerCallback> mCallback;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index d5cda85..b4fde16 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -21,7 +21,6 @@
 
 #include <android/os/IPullAtomCallback.h>
 #include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsPullerCallback.h>
 #include <cutils/log.h>
 #include <math.h>
 #include <stdint.h>
@@ -38,7 +37,6 @@
 #include "PowerStatsPuller.h"
 #include "ResourceHealthManagerPuller.h"
 #include "StatsCallbackPuller.h"
-#include "StatsCallbackPullerDeprecated.h"
 #include "StatsCompanionServicePuller.h"
 #include "SubsystemSleepStatePuller.h"
 #include "TrainInfoPuller.h"
@@ -68,13 +66,6 @@
         {{.atomTag = android::util::ON_DEVICE_POWER_MEASUREMENT},
          {.puller = new PowerStatsPuller()}},
 
-        // system_elapsed_realtime
-        {{.atomTag = android::util::SYSTEM_ELAPSED_REALTIME},
-         {.coolDownNs = NS_PER_SEC,
-          .puller = new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME),
-          .pullTimeoutNs = NS_PER_SEC / 2,
-         }},
-
         // remaining_battery_capacity
         {{.atomTag = android::util::REMAINING_BATTERY_CAPACITY},
          {.puller = new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
@@ -95,35 +86,6 @@
         {{.atomTag = android::util::BATTERY_CYCLE_COUNT},
          {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
 
-        // looper_stats
-        {{.atomTag = android::util::LOOPER_STATS},
-         {.additiveFields = {5, 6, 7, 8, 9},
-          .puller = new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
-
-        // Disk Stats
-        {{.atomTag = android::util::DISK_STATS},
-         {.puller = new StatsCompanionServicePuller(android::util::DISK_STATS)}},
-
-        // Directory usage
-        {{.atomTag = android::util::DIRECTORY_USAGE},
-         {.puller = new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
-
-        // Size of app's code, data, and cache
-        {{.atomTag = android::util::APP_SIZE},
-         {.puller = new StatsCompanionServicePuller(android::util::APP_SIZE)}},
-
-        // Size of specific categories of files. Eg. Music.
-        {{.atomTag = android::util::CATEGORY_SIZE},
-         {.puller = new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}},
-
-        // Number of fingerprints enrolled for each user.
-        {{.atomTag = android::util::NUM_FINGERPRINTS_ENROLLED},
-         {.puller = new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS_ENROLLED)}},
-
-        // Number of faces enrolled for each user.
-        {{.atomTag = android::util::NUM_FACES_ENROLLED},
-         {.puller = new StatsCompanionServicePuller(android::util::NUM_FACES_ENROLLED)}},
-
         // ProcStats.
         {{.atomTag = android::util::PROC_STATS},
          {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS)}},
@@ -132,20 +94,6 @@
         {{.atomTag = android::util::PROC_STATS_PKG_PROC},
          {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}},
 
-        // Disk I/O stats per uid.
-        {{.atomTag = android::util::DISK_IO},
-         {.additiveFields = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
-          .coolDownNs = 3 * NS_PER_SEC,
-          .puller = new StatsCompanionServicePuller(android::util::DISK_IO)}},
-
-        // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
-        {{.atomTag = android::util::PROCESS_CPU_TIME},
-         {.coolDownNs = 5 * NS_PER_SEC /* min cool-down in seconds*/,
-          .puller = new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
-        {{.atomTag = android::util::CPU_TIME_PER_THREAD_FREQ},
-         {.additiveFields = {7, 9, 11, 13, 15, 17, 19, 21},
-          .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_THREAD_FREQ)}},
-
         // DebugElapsedClock.
         {{.atomTag = android::util::DEBUG_ELAPSED_CLOCK},
          {.additiveFields = {1, 2, 3, 4},
@@ -156,25 +104,9 @@
          {.additiveFields = {1, 2, 3, 4},
           .puller = new StatsCompanionServicePuller(android::util::DEBUG_FAILING_ELAPSED_CLOCK)}},
 
-        // RoleHolder.
-        {{.atomTag = android::util::ROLE_HOLDER},
-         {.puller = new StatsCompanionServicePuller(android::util::ROLE_HOLDER)}},
-
-        // PermissionState.
-        {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE},
-         {.puller = new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE)}},
-
         // TrainInfo.
         {{.atomTag = android::util::TRAIN_INFO}, {.puller = new TrainInfoPuller()}},
 
-        // TimeZoneDataInfo.
-        {{.atomTag = android::util::TIME_ZONE_DATA_INFO},
-         {.puller = new StatsCompanionServicePuller(android::util::TIME_ZONE_DATA_INFO)}},
-
-        // ExternalStorageInfo
-        {{.atomTag = android::util::EXTERNAL_STORAGE_INFO},
-         {.puller = new StatsCompanionServicePuller(android::util::EXTERNAL_STORAGE_INFO)}},
-
         // GpuStatsGlobalInfo
         {{.atomTag = android::util::GPU_STATS_GLOBAL_INFO},
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)}},
@@ -183,31 +115,14 @@
         {{.atomTag = android::util::GPU_STATS_APP_INFO},
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}},
 
-        // AppsOnExternalStorageInfo
-        {{.atomTag = android::util::APPS_ON_EXTERNAL_STORAGE_INFO},
-         {.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
-
         // Face Settings
         {{.atomTag = android::util::FACE_SETTINGS},
          {.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
 
-        // App ops
-        {{.atomTag = android::util::APP_OPS},
-         {.puller = new StatsCompanionServicePuller(android::util::APP_OPS)}},
-
         // VmsClientStats
         {{.atomTag = android::util::VMS_CLIENT_STATS},
          {.additiveFields = {5, 6, 7, 8, 9, 10},
           .puller = new CarStatsPuller(android::util::VMS_CLIENT_STATS)}},
-
-        // NotiifcationRemoteViews.
-        {{.atomTag = android::util::NOTIFICATION_REMOTE_VIEWS},
-         {.puller = new StatsCompanionServicePuller(android::util::NOTIFICATION_REMOTE_VIEWS)}},
-
-        // PermissionStateSampled.
-        {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE_SAMPLED},
-         {.puller =
-               new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE_SAMPLED)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
@@ -406,21 +321,6 @@
     return totalCleared;
 }
 
-// Deprecated, remove after puller API is complete.
-void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
-        const sp<IStatsPullerCallback>& callback) {
-    AutoMutex _l(mLock);
-    // Platform pullers cannot be changed.
-    if (!isVendorPulledAtom(atomTag)) {
-        VLOG("RegisterPullerCallback: atom tag %d is not vendor pulled", atomTag);
-        return;
-    }
-    VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
-    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
-    kAllPullAtomInfo[{.atomTag = atomTag}] = {
-            .puller = new StatsCallbackPullerDeprecated(atomTag, callback)};
-}
-
 void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
                                                   const int64_t coolDownNs, const int64_t timeoutNs,
                                                   const vector<int32_t>& additiveFields,
@@ -437,16 +337,6 @@
     };
 }
 
-void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
-    AutoMutex _l(mLock);
-    // Platform pullers cannot be changed.
-    if (!isVendorPulledAtom(atomTag)) {
-        return;
-    }
-    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
-    kAllPullAtomInfo.erase({.atomTag = atomTag});
-}
-
 void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag) {
     AutoMutex _l(mLock);
     StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 349fd47..4b6ab57 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -18,7 +18,6 @@
 
 #include <android/os/IPullAtomCallback.h>
 #include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsPullerCallback.h>
 #include <binder/IServiceManager.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -116,15 +115,10 @@
 
     void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
 
-    // Deprecated, remove after puller API is complete.
-    void RegisterPullerCallback(int32_t atomTag, const sp<IStatsPullerCallback>& callback);
-
     void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
                                   const int64_t timeoutNs, const vector<int32_t>& additiveFields,
                                   const sp<IPullAtomCallback>& callback);
 
-    void UnregisterPullerCallback(int32_t atomTag);
-
     void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
 
     static std::map<PullerKey, PullAtomInfo> kAllPullAtomInfo;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 692d91e..3282785 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -164,9 +164,6 @@
     // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
     static const int kMaxNonPlatformPushedAtoms = 100;
 
-    // Max platform atom tag number.
-    static const int32_t kMaxPlatformAtomTag = 100000;
-
     // Vendor pulled atom start id.
     static const int32_t kVendorPulledAtomStartTag = 150000;
 
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 0bd8ce6..ee6ccc2 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -48,6 +48,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.os.HandlerCaller;
@@ -56,6 +57,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -392,7 +394,8 @@
     private static final String LOG_TAG = "AccessibilityService";
 
     /**
-     * Interface used by IAccessibilityServiceWrapper to call the service from its main thread.
+     * Interface used by IAccessibilityServiceClientWrapper to call the service from its main
+     * thread.
      * @hide
      */
     public interface Callbacks {
@@ -413,6 +416,8 @@
         /** Accessbility button clicked callbacks for different displays */
         void onAccessibilityButtonClicked(int displayId);
         void onAccessibilityButtonAvailabilityChanged(boolean available);
+        /** This is called when the system action list is changed. */
+        void onSystemActionsChanged();
     }
 
     /**
@@ -1643,6 +1648,29 @@
                 available);
     }
 
+    /** This is called when the system action list is changed. */
+    public void onSystemActionsChanged() {
+    }
+
+    /**
+     * Returns a list of system actions available in the system right now.
+     *
+     * @return A list of available system actions.
+     */
+    public final @NonNull List<AccessibilityAction> getSystemActions() {
+        IAccessibilityServiceConnection connection =
+                AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+        if (connection != null) {
+            try {
+                return connection.getSystemActions();
+            } catch (RemoteException re) {
+                Log.w(LOG_TAG, "Error while calling getSystemActions", re);
+                re.rethrowFromSystemServer();
+            }
+        }
+        return Collections.emptyList();
+    }
+
     /**
      * Performs a global action. Such an action can be performed
      * at any moment regardless of the current application or user
@@ -1894,6 +1922,11 @@
             public void onAccessibilityButtonAvailabilityChanged(boolean available) {
                 AccessibilityService.this.onAccessibilityButtonAvailabilityChanged(available);
             }
+
+            @Override
+            public void onSystemActionsChanged() {
+                AccessibilityService.this.onSystemActionsChanged();
+            }
         });
     }
 
@@ -1918,6 +1951,7 @@
         private static final int DO_ON_FINGERPRINT_GESTURE = 11;
         private static final int DO_ACCESSIBILITY_BUTTON_CLICKED = 12;
         private static final int DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 13;
+        private static final int DO_ON_SYSTEM_ACTIONS_CHANGED = 14;
 
         private final HandlerCaller mCaller;
 
@@ -2014,6 +2048,11 @@
             mCaller.sendMessage(message);
         }
 
+        /** This is called when the system action list is changed. */
+        public void onSystemActionsChanged() {
+            mCaller.sendMessage(mCaller.obtainMessage(DO_ON_SYSTEM_ACTIONS_CHANGED));
+        }
+
         @Override
         public void executeMessage(Message message) {
             switch (message.what) {
@@ -2035,14 +2074,14 @@
                             /* ignore - best effort */
                         }
                     }
-                } return;
-
+                    return;
+                }
                 case DO_ON_INTERRUPT: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         mCallback.onInterrupt();
                     }
-                } return;
-
+                    return;
+                }
                 case DO_INIT: {
                     mConnectionId = message.arg1;
                     SomeArgs args = (SomeArgs) message.obj;
@@ -2062,18 +2101,18 @@
                         AccessibilityInteractionClient.getInstance().clearCache();
                         mCallback.init(AccessibilityInteractionClient.NO_ID, null);
                     }
-                } return;
-
+                    return;
+                }
                 case DO_ON_GESTURE: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         mCallback.onGesture((AccessibilityGestureEvent) message.obj);
                     }
-                } return;
-
+                    return;
+                }
                 case DO_CLEAR_ACCESSIBILITY_CACHE: {
                     AccessibilityInteractionClient.getInstance().clearCache();
-                } return;
-
+                    return;
+                }
                 case DO_ON_KEY_EVENT: {
                     KeyEvent event = (KeyEvent) message.obj;
                     try {
@@ -2096,8 +2135,8 @@
                             /* ignore - best effort */
                         }
                     }
-                } return;
-
+                    return;
+                }
                 case DO_ON_MAGNIFICATION_CHANGED: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         final SomeArgs args = (SomeArgs) message.obj;
@@ -2110,45 +2149,53 @@
                         mCallback.onMagnificationChanged(displayId, region, scale,
                                 centerX, centerY);
                     }
-                } return;
-
+                    return;
+                }
                 case DO_ON_SOFT_KEYBOARD_SHOW_MODE_CHANGED: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         final int showMode = (int) message.arg1;
                         mCallback.onSoftKeyboardShowModeChanged(showMode);
                     }
-                } return;
-
+                    return;
+                }
                 case DO_GESTURE_COMPLETE: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         final boolean successfully = message.arg2 == 1;
                         mCallback.onPerformGestureResult(message.arg1, successfully);
                     }
-                } return;
+                    return;
+                }
                 case DO_ON_FINGERPRINT_ACTIVE_CHANGED: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         mCallback.onFingerprintCapturingGesturesChanged(message.arg1 == 1);
                     }
-                } return;
+                    return;
+                }
                 case DO_ON_FINGERPRINT_GESTURE: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         mCallback.onFingerprintGesture(message.arg1);
                     }
-                } return;
-
-                case (DO_ACCESSIBILITY_BUTTON_CLICKED): {
+                    return;
+                }
+                case DO_ACCESSIBILITY_BUTTON_CLICKED: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         mCallback.onAccessibilityButtonClicked(message.arg1);
                     }
-                } return;
-
-                case (DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED): {
+                    return;
+                }
+                case DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED: {
                     if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                         final boolean available = (message.arg1 != 0);
                         mCallback.onAccessibilityButtonAvailabilityChanged(available);
                     }
-                } return;
-
+                    return;
+                }
+                case DO_ON_SYSTEM_ACTIONS_CHANGED: {
+                    if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
+                        mCallback.onSystemActionsChanged();
+                    }
+                    return;
+                }
                 default :
                     Log.w(LOG_TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index 8ec3aea..58b0d19 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -55,4 +55,6 @@
     void onAccessibilityButtonClicked(int displayId);
 
     void onAccessibilityButtonAvailabilityChanged(boolean available);
+
+    void onSystemActionsChanged();
 }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 4ea5c62..5db4dd7 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -25,8 +25,10 @@
 import android.view.MagnificationSpec;
 import android.view.MotionEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 import android.view.accessibility.AccessibilityWindowInfo;
+import java.util.List;
 
 /**
  * Interface given to an AccessibilitySerivce to talk to the AccessibilityManagerService.
@@ -67,6 +69,7 @@
     AccessibilityServiceInfo getServiceInfo();
 
     boolean performGlobalAction(int action);
+    List<AccessibilityNodeInfo.AccessibilityAction> getSystemActions();
 
     void disableSelf();
 
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2010cc9..f7c4d96 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -22,6 +22,7 @@
 import android.Manifest;
 import android.annotation.DrawableRes;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -65,6 +66,7 @@
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.WorkSource;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
@@ -78,6 +80,7 @@
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.MemInfoReader;
+import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 
 import org.xmlpull.v1.XmlSerializer;
@@ -571,6 +574,8 @@
     @IntDef(flag = true, prefix = { "PROCESS_CAPABILITY_" }, value = {
             PROCESS_CAPABILITY_NONE,
             PROCESS_CAPABILITY_FOREGROUND_LOCATION,
+            PROCESS_CAPABILITY_FOREGROUND_CAMERA,
+            PROCESS_CAPABILITY_FOREGROUND_MICROPHONE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProcessCapability {}
@@ -583,9 +588,19 @@
     @TestApi
     public static final int PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1 << 0;
 
+    /** @hide Process can access camera while in foreground */
+    @TestApi
+    public static final int PROCESS_CAPABILITY_FOREGROUND_CAMERA = 1 << 1;
+
+    /** @hide Process can access microphone while in foreground */
+    @TestApi
+    public static final int PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 1 << 2;
+
     /** @hide all capabilities, the ORing of all flags in {@link ProcessCapability}*/
     @TestApi
-    public static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+    public static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION
+            | PROCESS_CAPABILITY_FOREGROUND_CAMERA
+            | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
 
     // NOTE: If PROCESS_STATEs are added, then new fields must be added
     // to frameworks/base/core/proto/android/app/enums.proto and the following method must
@@ -3479,6 +3494,50 @@
     }
 
     /**
+     * Return a list of {@link ApplicationExitInfo} records containing the reasons for the most
+     * recent app deaths.
+     *
+     * <p class="note"> Note: System stores this historical information in a ring buffer and only
+     * the most recent records will be returned. </p>
+     *
+     * <p class="note"> Note: In the case that this application was bound to an external service
+     * with flag {@link android.content.Context#BIND_EXTERNAL_SERVICE}, the process of that external
+     * service will be included in this package's exit info. </p>
+     *
+     * @param packageName Optional, a null value means match all packages belonging to the
+     *                    caller's UID. If this package belongs to another UID, you must hold
+     *                    {@link android.Manifest.permission#DUMP} in order to retrieve it.
+     * @param pid         A process ID that used to belong to this package but died later; a value
+     *                    of 0 means to ignore this parameter and return all matching records.
+     * @param maxNum      The maximum number of results to be returned; a value of 0
+     *                    means to ignore this parameter and return all matching records
+     *
+     * @return a list of {@link ApplicationExitInfo} records matching the criteria, sorted in
+     *         the order from most recent to least recent.
+     */
+    @Nullable
+    public List<ApplicationExitInfo> getHistoricalProcessExitReasons(@Nullable String packageName,
+            @IntRange(from = 0) int pid, @IntRange(from = 0) int maxNum) {
+        try {
+            ParceledListSlice<ApplicationExitInfo> r = getService().getHistoricalProcessExitReasons(
+                    packageName, pid, maxNum, mContext.getUserId());
+            return r == null ? null : r.getList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /*
+     * @return Whether or not the low memory kill will be reported in
+     * {@link #getHistoricalProcessExitReasons}.
+     *
+     * @see {@link ApplicationExitInfo#REASON_LOW_MEMORY}
+     */
+    public static boolean isLowMemoryKillReportSupported() {
+        return SystemProperties.getBoolean("persist.sys.lmk.reportkills", false);
+    }
+
+    /**
      * Return the importance of a given package name, based on the processes that are
      * currently running.  The return value is one of the importance constants defined
      * in {@link RunningAppProcessInfo}, giving you the highest importance of all the
@@ -4463,6 +4522,53 @@
     }
 
     /**
+     * Return if a given profile is in the foreground.
+     * @param userHandle UserHandle to check
+     * @return Returns the boolean result.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.CREATE_USERS
+    })
+    public boolean isProfileForeground(@NonNull UserHandle userHandle) {
+        UserManager userManager = mContext.getSystemService(UserManager.class);
+        if (userManager != null) {
+            for (UserInfo userInfo : userManager.getProfiles(getCurrentUser())) {
+                if (userInfo.id == userHandle.getIdentifier()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Kill the given PIDs, but the killing will be delayed until the device is idle
+     * and the given process is imperceptible.
+     *
+     * <p>You must hold the permission
+     * {@link android.Manifest.permission#FORCE_STOP_PACKAGES} to be able to
+     * call this method.
+     * </p>
+     *
+     * @param pids The list of the pids to be killed
+     * @pram reason The reason of the kill
+     *
+     * @hide
+     */
+    @SystemApi @TestApi
+    @RequiresPermission(Manifest.permission.FORCE_STOP_PACKAGES)
+    public void killProcessesWhenImperceptible(@NonNull int[] pids, @NonNull String reason) {
+        try {
+            getService().killProcessesWhenImperceptible(pids, reason);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * The AppTask allows you to manage your own application's tasks.
      * See {@link android.app.ActivityManager#getAppTasks()}
      */
@@ -4584,4 +4690,35 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Register with {@link HomeVisibilityObserver} with ActivityManager.
+     * @hide
+     */
+    @SystemApi
+    public void registerHomeVisibilityObserver(@NonNull HomeVisibilityObserver observer) {
+        Preconditions.checkNotNull(observer);
+        try {
+            observer.init(mContext, this);
+            getService().registerProcessObserver(observer.mObserver);
+            // Notify upon first registration.
+            observer.onHomeVisibilityChanged(observer.mIsHomeActivityVisible);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Unregister with {@link HomeVisibilityObserver} with ActivityManager.
+     * @hide
+     */
+    @SystemApi
+    public void unregisterHomeVisibilityObserver(@NonNull HomeVisibilityObserver observer) {
+        Preconditions.checkNotNull(observer);
+        try {
+            getService().unregisterProcessObserver(observer.mObserver);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java b/core/java/android/app/ApplicationExitInfo.aidl
similarity index 74%
copy from apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
copy to core/java/android/app/ApplicationExitInfo.aidl
index a534e22..fb7d8f6 100644
--- a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
+++ b/core/java/android/app/ApplicationExitInfo.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.server.permission;
+package android.app;
 
-/**
- * Persistence for runtime permissions.
- */
-public class RuntimePermissionPersistence {}
+parcelable ApplicationExitInfo;
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
new file mode 100644
index 0000000..4bf5f07
--- /dev/null
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -0,0 +1,901 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.ActivityManager.RunningAppProcessInfo.Importance;
+import android.icu.text.SimpleDateFormat;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.DebugUtils;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.WireTypeMismatchException;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * Describes the information of an application process's death.
+ *
+ * <p>
+ * Application process could die for many reasons, for example {@link #REASON_LOW_MEMORY}
+ * when it was killed by the ystem because it was running low on memory. Reason
+ * of the death can be retrieved via {@link #getReason}. Besides the reason, there are a few other
+ * auxiliary APIs like {@link #getStatus} and {@link #getImportance} to help the caller with
+ * additional diagnostic information.
+ * </p>
+ *
+ */
+public final class ApplicationExitInfo implements Parcelable {
+
+    /**
+     * Application process died due to unknown reason.
+     */
+    public static final int REASON_UNKNOWN = 0;
+
+    /**
+     * Application process exit normally by itself, for example,
+     * via {@link java.lang.System#exit}; {@link #getStatus} will specify the exit code.
+     *
+     * <p>Applications should normally not do this, as the system has a better knowledge
+     * in terms of process management.</p>
+     */
+    public static final int REASON_EXIT_SELF = 1;
+
+    /**
+     * Application process died due to the result of an OS signal; for example,
+     * {@link android.system.OsConstants#SIGKILL}; {@link #getStatus} will specify the signal
+     * number.
+     */
+    public static final int REASON_SIGNALED = 2;
+
+    /**
+     * Application process was killed by the system low memory killer, meaning the system was
+     * under memory pressure at the time of kill.
+     *
+     * <p class="note">
+     * Not all devices support reporting {@link #REASON_LOW_MEMORY}; on a device with no such
+     * support, when a process is killed due to memory pressure, the {@link #getReason} will return
+     * {@link #REASON_SIGNALED} and {@link #getStatus} will return
+     * the value {@link android.system.OsConstants#SIGKILL}.
+     *
+     * Application should use {@link ActivityManager#isLowMemoryKillReportSupported} to check
+     * if the device supports reporting {@link #REASON_LOW_MEMORY} or not.
+     * </p>
+     */
+    public static final int REASON_LOW_MEMORY = 3;
+
+    /**
+     * Application process died because of an unhandled exception in Java code.
+     */
+    public static final int REASON_CRASH = 4;
+
+    /**
+     * Application process died because of a native code crash.
+     */
+    public static final int REASON_CRASH_NATIVE = 5;
+
+    /**
+     * Application process was killed due to being unresponsive (ANR).
+     */
+    public static final int REASON_ANR = 6;
+
+    /**
+     * Application process was killed because of initialization failure,
+     * for example, it took too long to attach to the system during the start,
+     * or there was an error during initialization.
+     */
+    public static final int REASON_INITIALIZATION_FAILURE = 7;
+
+    /**
+     * Application process was killed due to a runtime permission change.
+     */
+    public static final int REASON_PERMISSION_CHANGE = 8;
+
+    /**
+     * Application process was killed by the system due to excessive resource usage.
+     */
+    public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9;
+
+    /**
+     * Application process was killed by the system for various other reasons,
+     * for example, the application package got disabled by the user;
+     * {@link #getDescription} will specify the cause given by the system.
+     */
+    public static final int REASON_OTHER = 10;
+
+    /**
+     * Application process kills subreason is unknown.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_UNKNOWN = 0;
+
+    /**
+     * Application process was killed because user quit it on the "wait for debugger" dialog;
+     * this would be set when the reason is {@link #REASON_OTHER}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_WAIT_FOR_DEBUGGER = 1;
+
+    /**
+     * Application process was killed by the activity manager because there were too many cached
+     * processes; this would be set only when the reason is {@link #REASON_OTHER}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_TOO_MANY_CACHED = 2;
+
+    /**
+     * Application process was killed by the activity manager because there were too many empty
+     * processes; this would be set only when the reason is {@link #REASON_OTHER}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_TOO_MANY_EMPTY = 3;
+
+    /**
+     * Application process was killed by the activity manager because there were too many cached
+     * processes and this process had been in empty state for a long time;
+     * this would be set only when the reason is {@link #REASON_OTHER}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_TRIM_EMPTY = 4;
+
+    /**
+     * Application process was killed by the activity manager because system was on memory pressure
+     * and this process took large amount of cached memory;
+     * this would be set only when the reason is {@link #REASON_OTHER}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_LARGE_CACHED = 5;
+
+    /**
+     * Application process was killed by the activity manager because the system was on low memory
+     * pressure for a significant amount of time since last idle;
+     * this would be set only when the reason is {@link #REASON_OTHER}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_MEMORY_PRESSURE = 6;
+
+    /**
+     * Application process was killed by the activity manager due to excessive CPU usage;
+     * this would be set only when the reason is {@link #REASON_EXCESSIVE_RESOURCE_USAGE}.
+     *
+     * For internal use only.
+     * @hide
+     */
+    public static final int SUBREASON_EXCESSIVE_CPU = 7;
+
+    /**
+     * @see {@link #getPid}
+     */
+    private int mPid;
+
+    /**
+     * @see {@link #getRealUid}
+     */
+    private int mRealUid;
+
+    /**
+     * @see {@link #getPackageUid}
+     */
+    private int mPackageUid;
+
+    /**
+     * @see {@link #getDefiningUid}
+     */
+    private int mDefiningUid;
+
+    /**
+     * @see {@link #getProcessName}
+     */
+    private String mProcessName;
+
+    /**
+     * @see {@link #getReason}
+     */
+    private @Reason int mReason;
+
+    /**
+     * @see {@link #getStatus}
+     */
+    private int mStatus;
+
+    /**
+     * @see {@link #getImportance}
+     */
+    private @Importance int mImportance;
+
+    /**
+     * @see {@link #getPss}
+     */
+    private int mPss;
+
+    /**
+     * @see {@link #getRss}
+     */
+    private int mRss;
+
+    /**
+     * @see {@link #getTimestamp}
+     */
+    private long mTimestamp;
+
+    /**
+     * @see {@link #getDescription}
+     */
+    private @Nullable String mDescription;
+
+    /**
+     * @see {@link #getSubReason}
+     */
+    private @SubReason int mSubReason;
+
+    /**
+     * @see {@link #getConnectionGroup}
+     */
+    private int mConnectionGroup;
+
+    /**
+     * @see {@link #getPackageName}
+     */
+    private String mPackageName;
+
+    /**
+     * @see {@link #getPackageList}
+     */
+    private String[] mPackageList;
+
+    /** @hide */
+    @IntDef(prefix = { "REASON_" }, value = {
+        REASON_UNKNOWN,
+        REASON_EXIT_SELF,
+        REASON_SIGNALED,
+        REASON_LOW_MEMORY,
+        REASON_CRASH,
+        REASON_CRASH_NATIVE,
+        REASON_ANR,
+        REASON_INITIALIZATION_FAILURE,
+        REASON_PERMISSION_CHANGE,
+        REASON_EXCESSIVE_RESOURCE_USAGE,
+        REASON_OTHER,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Reason {}
+
+    /** @hide */
+    @IntDef(prefix = { "SUBREASON_" }, value = {
+        SUBREASON_UNKNOWN,
+        SUBREASON_WAIT_FOR_DEBUGGER,
+        SUBREASON_TOO_MANY_CACHED,
+        SUBREASON_TOO_MANY_EMPTY,
+        SUBREASON_TRIM_EMPTY,
+        SUBREASON_LARGE_CACHED,
+        SUBREASON_MEMORY_PRESSURE,
+        SUBREASON_EXCESSIVE_CPU,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SubReason {}
+
+    /**
+     * The process id of the process that died.
+     */
+    public int getPid() {
+        return mPid;
+    }
+
+    /**
+     * The kernel user identifier of the process, most of the time the system uses this
+     * to do access control checks. It's typically the uid of the package where the component is
+     * running from, except the case of isolated process, where this field identifies the kernel
+     * user identifier that this process is actually running with, while the {@link #getPackageUid}
+     * identifies the kernel user identifier that is assigned at the package installation time.
+     */
+    public int getRealUid() {
+        return mRealUid;
+    }
+
+    /**
+     * Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the
+     * package installation time.
+     */
+    public int getPackageUid() {
+        return mPackageUid;
+    }
+
+    /**
+     * Return the defining kernel user identifier, maybe different from {@link #getRealUid} and
+     * {@link #getPackageUid}, if an external service was bound with the flag
+     * {@link android.content.Context#BIND_EXTERNAL_SERVICE} - in this case, this field here
+     * will be the kernel user identifier of the external service provider.
+     */
+    public int getDefiningUid() {
+        return mDefiningUid;
+    }
+
+    /**
+     * The actual process name it was running with.
+     */
+    public @NonNull String getProcessName() {
+        return mProcessName;
+    }
+
+    /**
+     * The reason code of the process's death.
+     */
+    public @Reason int getReason() {
+        return mReason;
+    }
+
+    /*
+     * The exit status argument of exit() if the application calls it, or the signal
+     * number if the application is signaled.
+     */
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * The importance of the process that it used to have before the death.
+     */
+    public @Importance int getImportance() {
+        return mImportance;
+    }
+
+    /*
+     * Last proportional set size of the memory that the process had used in kB.
+     *
+     * <p class="note">Note: This is the value from last sampling on the process,
+     * it's NOT the exact memory information prior to its death; and it'll be zero
+     * if the process died before system had a chance to take the sample. </p>
+     */
+    public int getPss() {
+        return mPss;
+    }
+
+    /**
+     * Last resident set size of the memory that the process had used in kB.
+     *
+     * <p class="note">Note: This is the value from last sampling on the process,
+     * it's NOT the exact memory information prior to its death; and it'll be zero
+     * if the process died before system had a chance to take the sample. </p>
+     */
+    public int getRss() {
+        return mRss;
+    }
+
+    /**
+     * The timestamp of the process's death, in milliseconds since the epoch.
+     */
+    public long getTimestamp() {
+        return mTimestamp;
+    }
+
+    /**
+     * The human readable description of the process's death, given by the system; could be null.
+     */
+    public @Nullable String getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * Return the user id of the record on a multi-user system.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @NonNull UserHandle getUserHandle() {
+        return UserHandle.of(UserHandle.getUserId(mRealUid));
+    }
+
+    /**
+     * A subtype reason in conjunction with {@link #mReason}.
+     *
+     * For internal use only.
+     *
+     * @hide
+     */
+    public @SubReason int getSubReason() {
+        return mSubReason;
+    }
+
+    /**
+     * The connection group this process belongs to, if there is any.
+     * @see {@link android.content.Context#updateServiceGroup}.
+     *
+     * For internal use only.
+     *
+     * @hide
+     */
+    public int getConnectionGroup() {
+        return mConnectionGroup;
+    }
+
+    /**
+     * Name of first package running in this process;
+     *
+     * For system internal use only, will not retain across processes.
+     *
+     * @hide
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * List of packages running in this process;
+     *
+     * For system internal use only, will not retain across processes.
+     *
+     * @hide
+     */
+    public String[] getPackageList() {
+        return mPackageList;
+    }
+
+    /**
+     * @see {@link #getPid}
+     *
+     * @hide
+     */
+    public void setPid(final int pid) {
+        mPid = pid;
+    }
+
+    /**
+     * @see {@link #getRealUid}
+     *
+     * @hide
+     */
+    public void setRealUid(final int uid) {
+        mRealUid = uid;
+    }
+
+    /**
+     * @see {@link #getPackageUid}
+     *
+     * @hide
+     */
+    public void setPackageUid(final int uid) {
+        mPackageUid = uid;
+    }
+
+    /**
+     * @see {@link #getDefiningUid}
+     *
+     * @hide
+     */
+    public void setDefiningUid(final int uid) {
+        mDefiningUid = uid;
+    }
+
+    /**
+     * @see {@link #getProcessName}
+     *
+     * @hide
+     */
+    public void setProcessName(final String processName) {
+        mProcessName = processName;
+    }
+
+    /**
+     * @see {@link #getReason}
+     *
+     * @hide
+     */
+    public void setReason(final @Reason int reason) {
+        mReason = reason;
+    }
+
+    /**
+     * @see {@link #getStatus}
+     *
+     * @hide
+     */
+    public void setStatus(final int status) {
+        mStatus = status;
+    }
+
+    /**
+     * @see {@link #getImportance}
+     *
+     * @hide
+     */
+    public void setImportance(final @Importance int importance) {
+        mImportance = importance;
+    }
+
+    /**
+     * @see {@link #getPss}
+     *
+     * @hide
+     */
+    public void setPss(final int pss) {
+        mPss = pss;
+    }
+
+    /**
+     * @see {@link #getRss}
+     *
+     * @hide
+     */
+    public void setRss(final int rss) {
+        mRss = rss;
+    }
+
+    /**
+     * @see {@link #getTimestamp}
+     *
+     * @hide
+     */
+    public void setTimestamp(final long timestamp) {
+        mTimestamp = timestamp;
+    }
+
+    /**
+     * @see {@link #getDescription}
+     *
+     * @hide
+     */
+    public void setDescription(final String description) {
+        mDescription = description;
+    }
+
+    /**
+     * @see {@link #getSubReason}
+     *
+     * @hide
+     */
+    public void setSubReason(final @SubReason int subReason) {
+        mSubReason = subReason;
+    }
+
+    /**
+     * @see {@link #getConnectionGroup}
+     *
+     * @hide
+     */
+    public void setConnectionGroup(final int connectionGroup) {
+        mConnectionGroup = connectionGroup;
+    }
+
+    /**
+     * @see {@link #getPackageName}
+     *
+     * @hide
+     */
+    public void setPackageName(final String packageName) {
+        mPackageName = packageName;
+    }
+
+    /**
+     * @see {@link #getPackageList}
+     *
+     * @hide
+     */
+    public void setPackageList(final String[] packageList) {
+        mPackageList = packageList;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mPid);
+        dest.writeInt(mRealUid);
+        dest.writeInt(mPackageUid);
+        dest.writeInt(mDefiningUid);
+        dest.writeString(mProcessName);
+        dest.writeInt(mConnectionGroup);
+        dest.writeInt(mReason);
+        dest.writeInt(mSubReason);
+        dest.writeInt(mStatus);
+        dest.writeInt(mImportance);
+        dest.writeInt(mPss);
+        dest.writeInt(mRss);
+        dest.writeLong(mTimestamp);
+        dest.writeString(mDescription);
+    }
+
+    /** @hide */
+    public ApplicationExitInfo() {
+    }
+
+    /** @hide */
+    public ApplicationExitInfo(ApplicationExitInfo other) {
+        mPid = other.mPid;
+        mRealUid = other.mRealUid;
+        mPackageUid = other.mPackageUid;
+        mDefiningUid = other.mDefiningUid;
+        mProcessName = other.mProcessName;
+        mConnectionGroup = other.mConnectionGroup;
+        mReason = other.mReason;
+        mStatus = other.mStatus;
+        mSubReason = other.mSubReason;
+        mImportance = other.mImportance;
+        mPss = other.mPss;
+        mRss = other.mRss;
+        mTimestamp = other.mTimestamp;
+        mDescription = other.mDescription;
+    }
+
+    private ApplicationExitInfo(@NonNull Parcel in) {
+        mPid = in.readInt();
+        mRealUid = in.readInt();
+        mPackageUid = in.readInt();
+        mDefiningUid = in.readInt();
+        mProcessName = in.readString();
+        mConnectionGroup = in.readInt();
+        mReason = in.readInt();
+        mSubReason = in.readInt();
+        mStatus = in.readInt();
+        mImportance = in.readInt();
+        mPss = in.readInt();
+        mRss = in.readInt();
+        mTimestamp = in.readLong();
+        mDescription = in.readString();
+    }
+
+    public @NonNull static final Creator<ApplicationExitInfo> CREATOR =
+            new Creator<ApplicationExitInfo>() {
+        @Override
+        public ApplicationExitInfo createFromParcel(Parcel in) {
+            return new ApplicationExitInfo(in);
+        }
+
+        @Override
+        public ApplicationExitInfo[] newArray(int size) {
+            return new ApplicationExitInfo[size];
+        }
+    };
+
+    /** @hide */
+    public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix,
+            @NonNull SimpleDateFormat sdf) {
+        pw.println(prefix + "ApplicationExitInfo " + seqSuffix + ":");
+        pw.println(prefix + "  timestamp=" + sdf.format(new Date(mTimestamp)));
+        pw.println(prefix + "  pid=" + mPid);
+        pw.println(prefix + "  realUid=" + mRealUid);
+        pw.println(prefix + "  packageUid=" + mPackageUid);
+        pw.println(prefix + "  definingUid=" + mDefiningUid);
+        pw.println(prefix + "  user=" + UserHandle.getUserId(mPackageUid));
+        pw.println(prefix + "  process=" + mProcessName);
+        pw.println(prefix + "  reason=" + mReason + " (" + reasonCodeToString(mReason) + ")");
+        pw.println(prefix + "  status=" + mStatus);
+        pw.println(prefix + "  importance=" + mImportance);
+        pw.print(prefix + "  pss="); DebugUtils.printSizeValue(pw, mPss << 10); pw.println();
+        pw.print(prefix + "  rss="); DebugUtils.printSizeValue(pw, mRss << 10); pw.println();
+        pw.println(prefix + "  description=" + mDescription);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("ApplicationExitInfo(timestamp=");
+        sb.append(new SimpleDateFormat().format(new Date(mTimestamp)));
+        sb.append(" pid=").append(mPid);
+        sb.append(" realUid=").append(mRealUid);
+        sb.append(" packageUid=").append(mPackageUid);
+        sb.append(" definingUid=").append(mDefiningUid);
+        sb.append(" user=").append(UserHandle.getUserId(mPackageUid));
+        sb.append(" process=").append(mProcessName);
+        sb.append(" reason=").append(mReason).append(" (")
+                .append(reasonCodeToString(mReason)).append(")");
+        sb.append(" status=").append(mStatus);
+        sb.append(" importance=").append(mImportance);
+        sb.append(" pss="); DebugUtils.sizeValueToString(mPss << 10, sb);
+        sb.append(" rss="); DebugUtils.sizeValueToString(mRss << 10, sb);
+        sb.append(" description=").append(mDescription);
+        return sb.toString();
+    }
+
+    private static String reasonCodeToString(@Reason int reason) {
+        switch (reason) {
+            case REASON_EXIT_SELF:
+                return "EXIT_SELF";
+            case REASON_SIGNALED:
+                return "SIGNALED";
+            case REASON_LOW_MEMORY:
+                return "LOW_MEMORY";
+            case REASON_CRASH:
+                return "APP CRASH(EXCEPTION)";
+            case REASON_CRASH_NATIVE:
+                return "APP CRASH(NATIVE)";
+            case REASON_ANR:
+                return "ANR";
+            case REASON_INITIALIZATION_FAILURE:
+                return "INITIALIZATION FAILURE";
+            case REASON_PERMISSION_CHANGE:
+                return "PERMISSION CHANGE";
+            case REASON_EXCESSIVE_RESOURCE_USAGE:
+                return "EXCESSIVE RESOURCE USAGE";
+            case REASON_OTHER:
+                return "OTHER KILLS BY SYSTEM";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /** @hide */
+    public static String subreasonToString(@SubReason int subreason) {
+        switch (subreason) {
+            case SUBREASON_WAIT_FOR_DEBUGGER:
+                return "WAIT FOR DEBUGGER";
+            case SUBREASON_TOO_MANY_CACHED:
+                return "TOO MANY CACHED PROCS";
+            case SUBREASON_TOO_MANY_EMPTY:
+                return "TOO MANY EMPTY PROCS";
+            case SUBREASON_TRIM_EMPTY:
+                return "TRIM EMPTY";
+            case SUBREASON_LARGE_CACHED:
+                return "LARGE CACHED";
+            case SUBREASON_MEMORY_PRESSURE:
+                return "MEMORY PRESSURE";
+            case SUBREASON_EXCESSIVE_CPU:
+                return "EXCESSIVE CPU USAGE";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Write to a protocol buffer output stream.
+     * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto}
+     *
+     * @param proto    Stream to write the ApplicationExitInfo object to.
+     * @param fieldId  Field Id of the ApplicationExitInfo as defined in the parent message
+     * @hide
+     */
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        final long token = proto.start(fieldId);
+        proto.write(ApplicationExitInfoProto.PID, mPid);
+        proto.write(ApplicationExitInfoProto.REAL_UID, mRealUid);
+        proto.write(ApplicationExitInfoProto.PACKAGE_UID, mPackageUid);
+        proto.write(ApplicationExitInfoProto.DEFINING_UID, mDefiningUid);
+        proto.write(ApplicationExitInfoProto.PROCESS_NAME, mProcessName);
+        proto.write(ApplicationExitInfoProto.CONNECTION_GROUP, mConnectionGroup);
+        proto.write(ApplicationExitInfoProto.REASON, mReason);
+        proto.write(ApplicationExitInfoProto.SUB_REASON, mSubReason);
+        proto.write(ApplicationExitInfoProto.STATUS, mStatus);
+        proto.write(ApplicationExitInfoProto.IMPORTANCE, mImportance);
+        proto.write(ApplicationExitInfoProto.PSS, mPss);
+        proto.write(ApplicationExitInfoProto.RSS, mRss);
+        proto.write(ApplicationExitInfoProto.TIMESTAMP, mTimestamp);
+        proto.write(ApplicationExitInfoProto.DESCRIPTION, mDescription);
+        proto.end(token);
+    }
+
+    /**
+     * Read from a protocol buffer input stream.
+     * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto}
+     *
+     * @param proto   Stream to read the ApplicationExitInfo object from.
+     * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message
+     * @hide
+     */
+    public void readFromProto(ProtoInputStream proto, long fieldId)
+            throws IOException, WireTypeMismatchException {
+        final long token = proto.start(fieldId);
+        while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (proto.getFieldNumber()) {
+                case (int) ApplicationExitInfoProto.PID:
+                    mPid = proto.readInt(ApplicationExitInfoProto.PID);
+                    break;
+                case (int) ApplicationExitInfoProto.REAL_UID:
+                    mRealUid = proto.readInt(ApplicationExitInfoProto.REAL_UID);
+                    break;
+                case (int) ApplicationExitInfoProto.PACKAGE_UID:
+                    mPackageUid = proto.readInt(ApplicationExitInfoProto.PACKAGE_UID);
+                    break;
+                case (int) ApplicationExitInfoProto.DEFINING_UID:
+                    mDefiningUid = proto.readInt(ApplicationExitInfoProto.DEFINING_UID);
+                    break;
+                case (int) ApplicationExitInfoProto.PROCESS_NAME:
+                    mProcessName = proto.readString(ApplicationExitInfoProto.PROCESS_NAME);
+                    break;
+                case (int) ApplicationExitInfoProto.CONNECTION_GROUP:
+                    mConnectionGroup = proto.readInt(ApplicationExitInfoProto.CONNECTION_GROUP);
+                    break;
+                case (int) ApplicationExitInfoProto.REASON:
+                    mReason = proto.readInt(ApplicationExitInfoProto.REASON);
+                    break;
+                case (int) ApplicationExitInfoProto.SUB_REASON:
+                    mSubReason = proto.readInt(ApplicationExitInfoProto.SUB_REASON);
+                    break;
+                case (int) ApplicationExitInfoProto.STATUS:
+                    mStatus = proto.readInt(ApplicationExitInfoProto.STATUS);
+                    break;
+                case (int) ApplicationExitInfoProto.IMPORTANCE:
+                    mImportance = proto.readInt(ApplicationExitInfoProto.IMPORTANCE);
+                    break;
+                case (int) ApplicationExitInfoProto.PSS:
+                    mPss = proto.readInt(ApplicationExitInfoProto.PSS);
+                    break;
+                case (int) ApplicationExitInfoProto.RSS:
+                    mRss = proto.readInt(ApplicationExitInfoProto.RSS);
+                    break;
+                case (int) ApplicationExitInfoProto.TIMESTAMP:
+                    mTimestamp = proto.readLong(ApplicationExitInfoProto.TIMESTAMP);
+                    break;
+                case (int) ApplicationExitInfoProto.DESCRIPTION:
+                    mDescription = proto.readString(ApplicationExitInfoProto.DESCRIPTION);
+                    break;
+            }
+        }
+        proto.end(token);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == null || !(other instanceof ApplicationExitInfo)) {
+            return false;
+        }
+        ApplicationExitInfo o = (ApplicationExitInfo) other;
+        return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid
+                && mDefiningUid == o.mDefiningUid
+                && mConnectionGroup == o.mConnectionGroup && mReason == o.mReason
+                && mSubReason == o.mSubReason && mImportance == o.mImportance
+                && mStatus == o.mStatus && mTimestamp == o.mTimestamp
+                && mPss == o.mPss && mRss == o.mRss
+                && TextUtils.equals(mProcessName, o.mProcessName)
+                && TextUtils.equals(mDescription, o.mDescription);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = mPid;
+        result = 31 * result + mRealUid;
+        result = 31 * result + mPackageUid;
+        result = 31 * result + mDefiningUid;
+        result = 31 * result + mConnectionGroup;
+        result = 31 * result + mReason;
+        result = 31 * result + mSubReason;
+        result = 31 * result + mImportance;
+        result = 31 * result + mStatus;
+        result = 31 * result + mPss;
+        result = 31 * result + mRss;
+        result = 31 * result + Long.hashCode(mTimestamp);
+        result = 31 * result + Objects.hashCode(mProcessName);
+        result = 31 * result + Objects.hashCode(mDescription);
+        return result;
+    }
+}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d39a8c4..fd56834 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -618,8 +618,7 @@
         return hasSystemFeature(name, 0);
     }
 
-    @Override
-    public boolean hasSystemFeature(String name, int version) {
+    private boolean hasSystemFeatureUncached(String name, int version) {
         try {
             return mPM.hasSystemFeature(name, version);
         } catch (RemoteException e) {
@@ -627,6 +626,64 @@
         }
     }
 
+    // Make this cache relatively large.  There are many system features and
+    // none are ever invalidated.  MPTS tests suggests that the cache should
+    // hold at least 150 entries.
+    private static final int SYS_FEATURE_CACHE_SIZE = 256;
+    private static final String CACHE_KEY_SYS_FEATURE_PROPERTY = "cache_key.has_system_feature";
+
+    private class SystemFeatureQuery {
+        public final String name;
+        public final int version;
+        public SystemFeatureQuery(String n, int v) {
+            name = n;
+            version = v;
+        }
+        @Override
+        public String toString() {
+            return String.format("SystemFeatureQuery(name=\"%s\", version=%d)",
+                    name, version);
+        }
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof SystemFeatureQuery) {
+                SystemFeatureQuery r = (SystemFeatureQuery) o;
+                return Objects.equals(name, r.name) &&  version == r.version;
+            } else {
+                return false;
+            }
+        }
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(name) + version;
+        }
+    }
+
+    private final PropertyInvalidatedCache<SystemFeatureQuery, Boolean> mSysFeatureCache =
+            new PropertyInvalidatedCache<SystemFeatureQuery, Boolean>(
+                SYS_FEATURE_CACHE_SIZE,
+                CACHE_KEY_SYS_FEATURE_PROPERTY) {
+                @Override
+                protected Boolean recompute(SystemFeatureQuery query) {
+                    return hasSystemFeatureUncached(query.name, query.version);
+                }
+            };
+
+    @Override
+    public boolean hasSystemFeature(String name, int version) {
+        return mSysFeatureCache.query(new SystemFeatureQuery(name, version)).booleanValue();
+    }
+
+    /** @hide */
+    public void disableSysFeatureCache() {
+        mSysFeatureCache.disableLocal();
+    }
+
+    /** @hide */
+    public static void invalidateSysFeatureCache() {
+        PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SYS_FEATURE_PROPERTY);
+    }
+
     @Override
     public int checkPermission(String permName, String pkgName) {
         try {
@@ -1675,6 +1732,10 @@
     }
 
     @UnsupportedAppUsage
+    protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
+        this(context, pm, ActivityThread.getPermissionManager());
+    }
+
     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm,
             IPermissionManager permissionManager) {
         mContext = context;
diff --git a/core/java/android/app/HomeVisibilityObserver.java b/core/java/android/app/HomeVisibilityObserver.java
new file mode 100644
index 0000000..f3465f8
--- /dev/null
+++ b/core/java/android/app/HomeVisibilityObserver.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+
+import java.util.List;
+
+/**
+ * An observer / callback to create and register by
+ * {@link ActivityManager#registerHomeVisibilityObserver} so that it's triggered when
+ * visibility of home page changes.
+ * @hide
+ */
+@SystemApi
+public abstract class HomeVisibilityObserver {
+    private Context mContext;
+    private ActivityManager mActivityManager;
+    /** @hide */
+    IProcessObserver.Stub mObserver;
+    /** @hide */
+    boolean mIsHomeActivityVisible;
+
+    /** @hide */
+    void init(Context context, ActivityManager activityManager) {
+        mContext = context;
+        mActivityManager = activityManager;
+        mIsHomeActivityVisible = isHomeActivityVisible();
+    }
+
+    /**
+     * The API that needs implemented and will be triggered when activity on home page changes.
+     */
+    public abstract void onHomeVisibilityChanged(boolean isHomeActivityVisible);
+
+    public HomeVisibilityObserver() {
+        mObserver = new IProcessObserver.Stub() {
+            @Override
+            public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) {
+                boolean isHomeActivityVisible = isHomeActivityVisible();
+                if (mIsHomeActivityVisible != isHomeActivityVisible) {
+                    mIsHomeActivityVisible = isHomeActivityVisible;
+                    onHomeVisibilityChanged(mIsHomeActivityVisible);
+                }
+            }
+
+            @Override
+            public void onForegroundServicesChanged(int pid, int uid, int fgServiceTypes) {
+            }
+
+            @Override
+            public void onProcessDied(int pid, int uid) {
+            }
+        };
+    }
+
+    private boolean isHomeActivityVisible() {
+        List<ActivityManager.RunningTaskInfo> tasks = mActivityManager.getRunningTasks(1);
+        if (tasks == null || tasks.isEmpty()) {
+            return false;
+        }
+
+        String top = tasks.get(0).topActivity.getPackageName();
+        if (top == null) {
+            return false;
+        }
+
+        // We can assume that the screen is idle if the home application is in the foreground.
+        final Intent intent = new Intent(Intent.ACTION_MAIN, null);
+        intent.addCategory(Intent.CATEGORY_HOME);
+
+        ResolveInfo info = mContext.getPackageManager().resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        if (info != null && top.equals(info.activityInfo.packageName)) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 580382e..7d04ca0 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -18,6 +18,7 @@
 
 import android.app.ActivityManager;
 import android.app.ApplicationErrorReport;
+import android.app.ApplicationExitInfo;
 import android.app.ContentProviderHolder;
 import android.app.GrantedUriPermission;
 import android.app.IApplicationThread;
@@ -604,4 +605,36 @@
      * Method for the app to tell system that it's wedged and would like to trigger an ANR.
      */
     void appNotResponding(String reason);
+
+    /**
+     * Return a list of {@link ApplicationExitInfo} records.
+     *
+     * <p class="note"> Note: System stores these historical information in a ring buffer, older
+     * records would be overwritten by newer records. </p>
+     *
+     * <p class="note"> Note: In the case that this application bound to an external service with
+     * flag {@link android.content.Context#BIND_EXTERNAL_SERVICE}, the process of that external
+     * service will be included in this package's exit info. </p>
+     *
+     * @param packageName Optional, an empty value means match all packages belonging to the
+     *                    caller's UID. If this package belongs to another UID, you must hold
+     *                    {@link android.Manifest.permission#DUMP} in order to retrieve it.
+     * @param pid         Optional, it could be a process ID that used to belong to this package but
+     *                    died later; A value of 0 means to ignore this parameter and return all
+     *                    matching records.
+     * @param maxNum      Optional, the maximum number of results should be returned; A value of 0
+     *                    means to ignore this parameter and return all matching records
+     * @param userId      The userId in the multi-user environment.
+     *
+     * @return a list of {@link ApplicationExitInfo} records with the matching criteria, sorted in
+     *         the order from most recent to least recent.
+     */
+    ParceledListSlice<ApplicationExitInfo> getHistoricalProcessExitReasons(String packageName,
+            int pid, int maxNum, int userId);
+
+    /*
+     * Kill the given PIDs, but the killing will be delayed until the device is idle
+     * and the given process is imperceptible.
+     */
+    void killProcessesWhenImperceptible(in int[] pids, String reason);
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 7af7a4a..f6014e5 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -95,7 +95,7 @@
     void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
     NotificationChannel getNotificationChannel(String callingPkg, int userId, String pkg, String channelId);
     NotificationChannel getConversationNotificationChannel(String callingPkg, int userId, String pkg, String channelId, boolean returnParentIfNoConversationChannel, String conversationId);
-    void createConversationNotificationChannelForPackage(String pkg, int uid, in NotificationChannel parentChannel, String conversationId);
+    void createConversationNotificationChannelForPackage(String pkg, int uid, String triggeringKey, in NotificationChannel parentChannel, String conversationId);
     NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId, boolean includeDeleted);
     void deleteNotificationChannel(String pkg, String channelId);
     void deleteConversationNotificationChannels(String pkg, int uid, String conversationId);
diff --git a/core/java/android/app/NotificationHistory.java b/core/java/android/app/NotificationHistory.java
index 8ba39a8..909a476 100644
--- a/core/java/android/app/NotificationHistory.java
+++ b/core/java/android/app/NotificationHistory.java
@@ -24,6 +24,8 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
@@ -311,11 +313,23 @@
         mHistoryCount++;
     }
 
+    /**
+     * Used when populating a history from disk; adds an historical notification.
+     */
+    public void addNewNotificationToWrite(@NonNull HistoricalNotification notification) {
+        if (notification == null) {
+            return;
+        }
+        mNotificationsToWrite.add(0, notification);
+        mHistoryCount++;
+    }
+
     public void addNotificationsToWrite(@NonNull NotificationHistory notificationHistory) {
         for (HistoricalNotification hn : notificationHistory.getNotificationsToWrite()) {
-            // TODO: consider merging by date
             addNotificationToWrite(hn);
         }
+        Collections.sort(mNotificationsToWrite,
+                (o1, o2) -> -1 * Long.compare(o1.getPostedTimeMs(), o2.getPostedTimeMs()));
         poolStringsFromNotifications();
     }
 
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index abb0cfc..3df1648 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -66,8 +66,9 @@
 
     /**
      * There will now be a callback to {@link
-     * OnSharedPreferenceChangeListener#onSharedPreferenceChanged(SharedPreferences, String)} with
-     * a {@code null} key on {@link Editor#clear()}.
+     * android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged
+     * OnSharedPreferenceChangeListener.onSharedPreferenceChanged} with a {@code null} key on
+     * {@link android.content.SharedPreferences.Editor#clear Editor.clear}.
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index dde6dda..0ea05d8 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -18,16 +18,16 @@
 import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.PACKAGE_USAGE_STATS;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.Context;
-import android.os.IBinder;
+import android.os.Binder;
 import android.os.IPullAtomCallback;
 import android.os.IPullAtomResultReceiver;
 import android.os.IStatsManagerService;
-import android.os.IStatsPullerCallback;
 import android.os.IStatsd;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -108,13 +108,11 @@
     /**
      * Value indicating that this pull was successful and that the result should be used.
      *
-     * @hide
      **/
     public static final int PULL_SUCCESS = 0;
 
     /**
      * Value indicating that this pull was unsuccessful and that the result should not be used.
-     * @hide
      **/
     public static final int PULL_SKIP = 1;
 
@@ -476,41 +474,16 @@
     }
 
     /**
-     * Registers a callback for an atom when that atom is to be pulled. The stats service will
-     * invoke pullData in the callback when the stats service determines that this atom needs to be
-     * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
-     *
-     * @param atomTag   The tag of the atom for this puller callback. Must be at least 100000.
-     * @param callback  The callback to be invoked when the stats service pulls the atom.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
+     * Temp registration for while the migration is in progress.
      *
      * @hide
-     * @deprecated Please use registerPullAtomCallback
      */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
-            throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsd service = getIStatsdLocked();
-                if (callback == null) {
-                    service.unregisterPullerCallback(atomTag, mContext.getOpPackageName());
-                } else {
-                    service.registerPullerCallback(atomTag, callback,
-                            mContext.getOpPackageName());
-                }
-
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to connect to statsd when registering data listener.");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
+    public void registerPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
+            @NonNull StatsPullAtomCallback callback,
+            @NonNull @CallbackExecutor Executor executor) {
+        registerPullAtomCallback(atomTag, metadata, executor, callback);
     }
 
-
     /**
      * Registers a callback for an atom when that atom is to be pulled. The stats service will
      * invoke pullData in the callback when the stats service determines that this atom needs to be
@@ -520,18 +493,19 @@
      * @param metadata          Optional metadata specifying the timeout, cool down time, and
      *                          additive fields for mapping isolated to host uids.
      * @param callback          The callback to be invoked when the stats service pulls the atom.
-     * @param executor          The executor in which to run the callback
+     * @param executor          The executor in which to run the callback.
      *
-     * @hide
      */
     public void registerPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
-            @NonNull StatsPullAtomCallback callback, @NonNull Executor executor) {
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull StatsPullAtomCallback callback) {
         long coolDownNs = metadata == null ? DEFAULT_COOL_DOWN_NS : metadata.mCoolDownNs;
         long timeoutNs = metadata == null ? DEFAULT_TIMEOUT_NS : metadata.mTimeoutNs;
         int[] additiveFields = metadata == null ? new int[0] : metadata.mAdditiveFields;
         if (additiveFields == null) {
             additiveFields = new int[0];
         }
+
         synchronized (sLock) {
             try {
                 IStatsManagerService service = getIStatsManagerServiceLocked();
@@ -551,7 +525,6 @@
      *
      * @param atomTag           The tag of the atom of which to unregister
      *
-     * @hide
      */
     public void unregisterPullAtomCallback(int atomTag) {
         synchronized (sLock) {
@@ -577,21 +550,26 @@
 
         @Override
         public void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver) {
-            mExecutor.execute(() -> {
-                List<StatsEvent> data = new ArrayList<>();
-                int successInt = mCallback.onPullAtom(atomTag, data);
-                boolean success = successInt == PULL_SUCCESS;
-                StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
-                for (int i = 0; i < data.size(); i++) {
-                    parcels[i] = new StatsEventParcel();
-                    parcels[i].buffer = data.get(i).getBytes();
-                }
-                try {
-                    resultReceiver.pullFinished(atomTag, success, parcels);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
-                }
-            });
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    List<StatsEvent> data = new ArrayList<>();
+                    int successInt = mCallback.onPullAtom(atomTag, data);
+                    boolean success = successInt == PULL_SUCCESS;
+                    StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
+                    for (int i = 0; i < data.size(); i++) {
+                        parcels[i] = new StatsEventParcel();
+                        parcels[i].buffer = data.get(i).getBytes();
+                    }
+                    try {
+                        resultReceiver.pullFinished(atomTag, success, parcels);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
     }
 
@@ -599,7 +577,6 @@
      * Metadata required for registering a StatsPullAtomCallback.
      * All fields are optional, and defaults will be used for fields that are unspecified.
      *
-     * @hide
      */
     public static class PullAtomMetadata {
         private final long mCoolDownNs;
@@ -614,22 +591,27 @@
         }
 
         /**
-         * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
-         * StatsManager#registerPullAtomCallback
+         * Temp for while migrations are in progress.
+         *
+         * @hide
          */
         public static PullAtomMetadata.Builder newBuilder() {
             return new PullAtomMetadata.Builder();
         }
 
         /**
-         * Builder for PullAtomMetadata.
+         *  Builder for PullAtomMetadata.
          */
         public static class Builder {
             private long mCoolDownNs;
             private long mTimeoutNs;
             private int[] mAdditiveFields;
 
-            private Builder() {
+            /**
+             * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
+             * StatsManager#registerPullAtomCallback
+             */
+            public Builder() {
                 mCoolDownNs = DEFAULT_COOL_DOWN_NS;
                 mTimeoutNs = DEFAULT_TIMEOUT_NS;
                 mAdditiveFields = null;
@@ -662,7 +644,7 @@
              * will be combined when the non-additive fields are the same.
              */
             @NonNull
-            public Builder setAdditiveFields(int[] additiveFields) {
+            public Builder setAdditiveFields(@NonNull int[] additiveFields) {
                 mAdditiveFields = additiveFields;
                 return this;
             }
@@ -705,40 +687,13 @@
     /**
      * Callback interface for pulling atoms requested by the stats service.
      *
-     * @hide
      */
     public interface StatsPullAtomCallback {
         /**
          * Pull data for the specified atom tag, filling in the provided list of StatsEvent data.
          * @return {@link #PULL_SUCCESS} if the pull was successful, or {@link #PULL_SKIP} if not.
          */
-        int onPullAtom(int atomTag, List<StatsEvent> data);
-    }
-
-    private class StatsdDeathRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            synchronized (sLock) {
-                mService = null;
-            }
-        }
-    }
-
-    @GuardedBy("sLock")
-    private IStatsd getIStatsdLocked() throws StatsUnavailableException {
-        if (mService != null) {
-            return mService;
-        }
-        mService = IStatsd.Stub.asInterface(ServiceManager.getService("stats"));
-        if (mService == null) {
-            throw new StatsUnavailableException("could not be found");
-        }
-        try {
-            mService.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
-        } catch (RemoteException e) {
-            throw new StatsUnavailableException("could not connect when linkToDeath", e);
-        }
-        return mService;
+        int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
     }
 
     @GuardedBy("sLock")
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 7b21f12..c1e5356 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -148,6 +148,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemConfigManager;
 import android.os.SystemUpdateManager;
 import android.os.SystemVibrator;
 import android.os.UserHandle;
@@ -627,6 +628,13 @@
                         return new SystemUpdateManager(service);
                     }});
 
+        registerService(Context.SYSTEM_CONFIG_SERVICE, SystemConfigManager.class,
+                new CachedServiceFetcher<SystemConfigManager>() {
+                    @Override
+                    public SystemConfigManager createService(ContextImpl ctx) {
+                        return new SystemConfigManager();
+                    }});
+
         registerService(Context.TELEPHONY_REGISTRY_SERVICE, TelephonyRegistryManager.class,
             new CachedServiceFetcher<TelephonyRegistryManager>() {
                 @Override
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 2579bd1..35cf687 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1254,6 +1254,11 @@
                 }
 
                 @Override
+                public void onSystemActionsChanged() {
+                    /* do nothing */
+                }
+
+                @Override
                 public boolean onGesture(AccessibilityGestureEvent gestureEvent) {
                     /* do nothing */
                     return false;
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 9ad3d38..a885009 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1564,6 +1564,8 @@
      * @return The desired minimum width for the wallpaper. This value should
      * be honored by applications that set the wallpaper but it is not
      * mandatory.
+     *
+     * @see #getDesiredMinimumHeight()
      */
     public int getDesiredMinimumWidth() {
         if (sGlobals.mService == null) {
@@ -1590,6 +1592,8 @@
      * @return The desired minimum height for the wallpaper. This value should
      * be honored by applications that set the wallpaper but it is not
      * mandatory.
+     *
+     * @see #getDesiredMinimumWidth()
      */
     public int getDesiredMinimumHeight() {
         if (sGlobals.mService == null) {
@@ -1609,12 +1613,11 @@
      * a virtual wallpaper that is larger than the physical screen, matching
      * the size of their workspace.
      *
-     * <p>Note developers, who don't seem to be reading this.  This is
-     * for <em>home apps</em> to tell what size wallpaper they would like.
-     * Nobody else should be calling this!  Certainly not other non-home
-     * apps that change the wallpaper.  Those apps are supposed to
-     * <b>retrieve</b> the suggested size so they can construct a wallpaper
-     * that matches it.
+     * <p class="note">Calling this method from apps other than the active
+     * home app is not guaranteed to work properly.  Other apps that supply
+     * wallpaper imagery should use {@link #getDesiredMinimumWidth()} and
+     * {@link #getDesiredMinimumHeight()} and construct a wallpaper that
+     * matches those dimensions.
      *
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#SET_WALLPAPER_HINTS}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 54a64ef..a35a899 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8605,6 +8605,55 @@
     }
 
     /**
+     * Called by a device owner or a profile owner of an organization-owned managed profile to
+     * control whether the user can change networks configured by the admin.
+     * <p>
+     * WiFi network configuration lockdown is controlled by a global settings
+     * {@link android.provider.Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN} and calling
+     * this API effectively modifies the global settings. Previously device owners can also
+     * control this directly via {@link #setGlobalSetting} but they are recommended to switch
+     * to this API.
+     *
+     * @param admin             admin Which {@link DeviceAdminReceiver} this request is associated
+     *                          with.
+     * @param lockdown Whether the admin configured networks should be unmodifiable by the
+     *                          user.
+     * @throws SecurityException if caller is not a device owner or a profile owner of an
+     *                           organization-owned managed profile.
+     */
+    public void setLockdownAdminConfiguredNetworks(@NonNull ComponentName admin, boolean lockdown) {
+        throwIfParentInstance("setLockdownAdminConfiguredNetworks");
+        if (mService != null) {
+            try {
+                mService.setLockdownAdminConfiguredNetworks(admin, lockdown);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Called by a device owner or a profile owner of an organization-owned managed profile to
+     * determine whether the user is prevented from modifying networks configured by the admin.
+     *
+     * @param admin             admin Which {@link DeviceAdminReceiver} this request is associated
+     *                          with.
+     * @throws SecurityException if caller is not a device owner or a profile owner of an
+     *                           organization-owned managed profile.
+     */
+    public boolean isLockdownAdminConfiguredNetworks(@NonNull ComponentName admin) {
+        throwIfParentInstance("setLockdownAdminConfiguredNetworks");
+        if (mService != null) {
+            try {
+                return mService.isLockdownAdminConfiguredNetworks(admin);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Called by a device owner or a profile owner of an organization-owned managed
      * profile to set the system wall clock time. This only takes effect if called when
      * {@link android.provider.Settings.Global#AUTO_TIME} is 0, otherwise {@code false}
@@ -11468,6 +11517,7 @@
      * @throws SecurityException if {@code admin} is not a device owner.
      */
     public void setProtectedPackages(@NonNull ComponentName admin, @NonNull List<String> packages) {
+        throwIfParentInstance("setProtectedPackages");
         if (mService != null) {
             try {
                 mService.setProtectedPackages(admin, packages);
@@ -11484,6 +11534,7 @@
      * @throws SecurityException if {@code admin} is not a device owner.
      */
     public @NonNull List<String> getProtectedPackages(@NonNull ComponentName admin) {
+        throwIfParentInstance("getProtectedPackages");
         if (mService != null) {
             try {
                 return mService.getProtectedPackages(admin);
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index f649286..a2c0856 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -263,6 +263,9 @@
     void setSystemSetting(in ComponentName who, in String setting, in String value);
     void setSecureSetting(in ComponentName who, in String setting, in String value);
 
+    void setLockdownAdminConfiguredNetworks(in ComponentName who, boolean lockdown);
+    boolean isLockdownAdminConfiguredNetworks(in ComponentName who);
+
     void setLocationEnabled(in ComponentName who, boolean locationEnabled);
 
     boolean setTime(in ComponentName who, long millis);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3df94a7..2943e39 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5020,6 +5020,14 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
+     * {@link android.os.SystemConfigManager}.
+     * @hide
+     */
+    @SystemApi
+    public static final String SYSTEM_CONFIG_SERVICE = "system_config";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve an
      * {@link android.telephony.ims.RcsMessageManager}.
      * @hide
      */
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ee75802..c8c3102 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4021,6 +4021,7 @@
      * <p>
      * @see #EXTRA_SIM_STATE
      * @see #EXTRA_SIM_LOCKED_REASON
+     * @see #EXTRA_REBROADCAST_ON_UNLOCK
      *
      * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED} or
      * {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
@@ -4197,6 +4198,18 @@
     public static final String SIM_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
 
     /**
+     * The extra used with {@link #ACTION_SIM_STATE_CHANGED} for indicating whether this broadcast
+     * is a rebroadcast on unlock. Defaults to {@code false} if not specified.
+     *
+     * @hide
+     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED} or
+     * {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_REBROADCAST_ON_UNLOCK = "rebroadcastOnUnlock";
+
+    /**
      * Broadcast Action: indicate that the phone service state has changed.
      * The intent will have the following extra values:</p>
      * <p>
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index 6954b31..33bd839 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
 import android.os.Binder;
 import android.os.Process;
 
@@ -67,22 +68,30 @@
  * @hide
  */
 public final class PermissionChecker {
-    /** Permission result: The permission is granted. */
+    /** The permission is granted. */
     public static final int PERMISSION_GRANTED =  PackageManager.PERMISSION_GRANTED;
 
-    /** Permission result: The permission is denied. */
-    public static final int PERMISSION_DENIED =  PackageManager.PERMISSION_DENIED;
+    /** Returned when:
+     * <ul>
+     * <li>For non app op permissions, returned when the permission is denied.</li>
+     * <li>For app op permissions, returned when the app op is denied or app op is
+     * {@link AppOpsManager#MODE_DEFAULT} and permission is denied.</li>
+     * </ul>
+     *
+     */
+    public static final int PERMISSION_HARD_DENIED =  PackageManager.PERMISSION_DENIED;
 
-    /** Permission result: The permission is denied because the app op is not allowed. */
-    public static final int PERMISSION_DENIED_APP_OP =  PackageManager.PERMISSION_DENIED  - 1;
+    /** Only for runtime permissions, its returned when the runtime permission
+     * is granted, but the corresponding app op is denied. */
+    public static final int PERMISSION_SOFT_DENIED =  PackageManager.PERMISSION_DENIED - 1;
 
     /** Constant when the PID for which we check permissions is unknown. */
     public static final int PID_UNKNOWN = -1;
 
     /** @hide */
     @IntDef({PERMISSION_GRANTED,
-            PERMISSION_DENIED,
-            PERMISSION_DENIED_APP_OP})
+            PERMISSION_SOFT_DENIED,
+            PERMISSION_HARD_DENIED})
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionResult {}
 
@@ -116,7 +125,7 @@
      *     the first package for the calling UID will be used.
      * @param featureId Feature in the package
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      * @param message A message describing the reason the permission was checked
      *
      * @see #checkPermissionForPreflight(Context, String, int, int, String)
@@ -155,7 +164,7 @@
      * @param packageName The package name for which to check. If null the
      *     the first package for the calling UID will be used.
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      *
      * @see #checkPermissionForDataDelivery(Context, String, int, int, String, String)
      */
@@ -189,7 +198,7 @@
      * @param context Context for accessing resources.
      * @param permission The permission to check.
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      * @param message A message describing the reason the permission was checked
      *
      * @see #checkSelfPermissionForPreflight(Context, String)
@@ -225,7 +234,7 @@
      * @param context Context for accessing resources.
      * @param permission The permission to check.
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      *
      * @see #checkSelfPermissionForDataDelivery(Context, String, String)
      */
@@ -259,7 +268,7 @@
      *     the first package for the calling UID will be used.
      * @param featureId The feature inside of the app
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      * @param message A message describing the reason the permission was checked
      *
      * @see #checkCallingPermissionForPreflight(Context, String, String)
@@ -269,7 +278,7 @@
             @NonNull String permission, @Nullable String packageName,
             @Nullable String featureId, @Nullable String message) {
         if (Binder.getCallingPid() == Process.myPid()) {
-            return PERMISSION_DENIED;
+            return PERMISSION_HARD_DENIED;
         }
         return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
                 Binder.getCallingUid(), packageName, featureId, message);
@@ -299,7 +308,7 @@
      * @param packageName The package name making the IPC. If null the
      *     the first package for the calling UID will be used.
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      *
      * @see #checkCallingPermissionForDataDelivery(Context, String, String, String)
      */
@@ -307,7 +316,7 @@
     public static int checkCallingPermissionForPreflight(@NonNull Context context,
             @NonNull String permission, @Nullable String packageName) {
         if (Binder.getCallingPid() == Process.myPid()) {
-            return PERMISSION_DENIED;
+            return PERMISSION_HARD_DENIED;
         }
         return checkPermissionForPreflight(context, permission, Binder.getCallingPid(),
                 Binder.getCallingUid(), packageName);
@@ -333,7 +342,7 @@
      * @param context Context for accessing resources.
      * @param permission The permission to check.
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      * @param featureId feature Id of caller (if not self)
      * @param message A message describing the reason the permission was checked
      *
@@ -372,7 +381,7 @@
      * @param context Context for accessing resources.
      * @param permission The permission to check.
      * @return The permission check result which is either {@link #PERMISSION_GRANTED}
-     *     or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+     *     or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}.
      *
      * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String, String)
      */
@@ -385,39 +394,85 @@
                 Binder.getCallingUid(), packageName);
     }
 
-    private static int checkPermissionCommon(@NonNull Context context, @NonNull String permission,
+    static int checkPermissionCommon(@NonNull Context context, @NonNull String permission,
             int pid, int uid, @Nullable String packageName, @Nullable String featureId,
             @Nullable String message, boolean forDataDelivery) {
-        if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
-            return PERMISSION_DENIED;
-        }
-
-        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-        String op = appOpsManager.permissionToOp(permission);
-        if (op == null) {
-            return PERMISSION_GRANTED;
+        final PermissionInfo permissionInfo;
+        try {
+            // TODO(b/147869157): Cache platform defined app op and runtime permissions to avoid
+            // calling into the package manager every time.
+            permissionInfo = context.getPackageManager().getPermissionInfo(permission, 0);
+        } catch (PackageManager.NameNotFoundException ignored) {
+            return PERMISSION_HARD_DENIED;
         }
 
         if (packageName == null) {
             String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
-            if (packageNames == null || packageNames.length <= 0) {
-                return PERMISSION_DENIED;
+            if (packageNames != null && packageNames.length > 0) {
+                packageName = packageNames[0];
             }
-            packageName = packageNames[0];
         }
 
-        if (forDataDelivery) {
-            if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid, featureId, message)
-                    != AppOpsManager.MODE_ALLOWED) {
-                return PERMISSION_DENIED_APP_OP;
+        if (permissionInfo.isAppOp()) {
+            return checkAppOpPermission(context, permission, pid, uid, packageName, featureId,
+                    message, forDataDelivery);
+        }
+        if (permissionInfo.isRuntime()) {
+            return checkRuntimePermission(context, permission, pid, uid, packageName, featureId,
+                    message, forDataDelivery);
+        }
+        return context.checkPermission(permission, pid, uid);
+    }
+
+    private static int checkAppOpPermission(@NonNull Context context, @NonNull String permission,
+            int pid, int uid, @Nullable String packageName, @Nullable String featureId,
+            @Nullable String message, boolean forDataDelivery) {
+        final String op = AppOpsManager.permissionToOp(permission);
+        if (op == null || packageName == null) {
+            return PERMISSION_HARD_DENIED;
+        }
+
+        final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+        final int opMode = (forDataDelivery)
+                ? appOpsManager.noteProxyOpNoThrow(op, packageName, uid, featureId, message)
+                : appOpsManager.unsafeCheckOpNoThrow(op, uid, packageName);
+
+        switch (opMode) {
+            case AppOpsManager.MODE_ALLOWED: {
+                return PERMISSION_GRANTED;
             }
+            case AppOpsManager.MODE_DEFAULT: {
+                return context.checkPermission(permission, pid, uid)
+                            == PackageManager.PERMISSION_GRANTED
+                        ? PERMISSION_GRANTED : PERMISSION_HARD_DENIED;
+            }
+            default: {
+                return PERMISSION_HARD_DENIED;
+            }
+        }
+    }
+
+    private static int checkRuntimePermission(@NonNull Context context, @NonNull String permission,
+            int pid, int uid, @Nullable String packageName, @Nullable String featureId,
+            @Nullable String message, boolean forDataDelivery) {
+        if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
+            return PERMISSION_HARD_DENIED;
+        }
+
+        final String op = AppOpsManager.permissionToOp(permission);
+        if (op == null || packageName == null) {
+            return PERMISSION_GRANTED;
+        }
+
+        final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+        final int opMode = (forDataDelivery)
+                ? appOpsManager.noteProxyOpNoThrow(op, packageName, uid, featureId, message)
+                : appOpsManager.unsafeCheckOpNoThrow(op, uid, packageName);
+
+        if (opMode == AppOpsManager.MODE_ALLOWED) {
+            return PERMISSION_GRANTED;
         } else {
-            final int mode = appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName);
-            if (mode != AppOpsManager.MODE_ALLOWED && mode != AppOpsManager.MODE_FOREGROUND) {
-                return PERMISSION_DENIED_APP_OP;
-            }
+            return PERMISSION_SOFT_DENIED;
         }
-
-        return PERMISSION_GRANTED;
     }
 }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index e5daaca..622588b 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -290,6 +290,15 @@
     public int colorMode = COLOR_MODE_DEFAULT;
 
     /**
+     * Value for {@link #preferMinimalPostProcessing} indicating that by default
+     * minimal post processing is not preferred.
+     *
+     * @see android.R.attr#preferMinimalPostProcessing
+     * @hide
+     */
+    public static final boolean MINIMAL_POST_PROCESSING_DEFAULT = false;
+
+    /**
      * Indicates whether the activity wants the connected display to do minimal post processing on
      * the produced image or video frames. This will only be requested if this activity's main
      * window is visible on the screen.
@@ -315,7 +324,7 @@
      * @see android.view.WindowManager.LayoutParams#preferMinimalPostProcessing
      * @see android.view.Display#isMinimalPostProcessingSupported
      */
-    public boolean preferMinimalPostProcessing = false;
+    public boolean preferMinimalPostProcessing = MINIMAL_POST_PROCESSING_DEFAULT;
 
     /**
      * Bit in {@link #flags} indicating whether this activity is able to
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 9d57514..5aa9c9b 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.app.AppOpsManager.Mode;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -42,6 +43,18 @@
  * use this class to start its main activity in managed profile.
  */
 public class CrossProfileApps {
+
+    /**
+     * Broadcast signalling that the receiving app's ability to interact across profiles has
+     * changed, as defined by the return value of {@link #canInteractAcrossProfiles()}.
+     *
+     * <p>Apps that have set the {@code android:crossProfile} manifest attribute to {@code true}
+     * can receive this broadcast in manifest broadcast receivers. Otherwise, it can only be
+     * received by dynamically-registered broadcast receivers.
+     */
+    public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED =
+            "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED";
+
     private final Context mContext;
     private final ICrossProfileApps mService;
     private final UserManager mUserManager;
@@ -254,6 +267,38 @@
         return settingsIntent;
     }
 
+    /**
+     * Sets the app-op for {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} that is
+     * configurable by users in Settings. This configures it for the profile group of the calling
+     * package.
+     *
+     * <p>Before calling, check {@link #canRequestInteractAcrossProfiles()} and do not call if it is
+     * {@code false}. If presenting a user interface, do not allow the user to configure the app-op
+     * in that case.
+     *
+     * <p>The underlying app-op {@link android.app.AppOpsManager#OP_INTERACT_ACROSS_PROFILES} should
+     * never be set directly. This method ensures that the app-op is kept in sync for the app across
+     * each user in the profile group and that those apps are sent a broadcast when their ability to
+     * interact across profiles changes.
+     *
+     * <p>This method should be used whenever an app's ability to interact across profiles changes,
+     * as defined by the return value of {@link #canInteractAcrossProfiles()}. This includes user
+     * consent changes in Settings or during provisioning, plus changes to the admin or OEM consent
+     * whitelists that make the current app-op value invalid.
+     *
+     * @hide
+     */
+    @RequiresPermission(
+            allOf={android.Manifest.permission.MANAGE_APP_OPS_MODES,
+                    android.Manifest.permission.INTERACT_ACROSS_USERS})
+    public void setInteractAcrossProfilesAppOp(@NonNull String packageName, @Mode int newMode) {
+        try {
+            mService.setInteractAcrossProfilesAppOp(packageName, newMode);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     private void verifyCanAccessUser(UserHandle userHandle) {
         if (!getTargetUserProfiles().contains(userHandle)) {
             throw new SecurityException("Not allowed to access " + userHandle);
diff --git a/core/java/android/content/pm/ICrossProfileApps.aidl b/core/java/android/content/pm/ICrossProfileApps.aidl
index c5db0cc..694b1a3 100644
--- a/core/java/android/content/pm/ICrossProfileApps.aidl
+++ b/core/java/android/content/pm/ICrossProfileApps.aidl
@@ -32,4 +32,5 @@
     List<UserHandle> getTargetUserProfiles(in String callingPackage);
     boolean canInteractAcrossProfiles(in String callingPackage);
     boolean canRequestInteractAcrossProfiles(in String callingPackage);
+    void setInteractAcrossProfilesAppOp(in String packageName, int newMode);
 }
\ No newline at end of file
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index e954635..e86bb25 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -36,7 +36,7 @@
 
     void close();
     void commit(in IntentSender statusReceiver, boolean forTransferred);
-    void transfer(in String packageName, in IntentSender statusReceiver);
+    void transfer(in String packageName);
     void abandon();
 
     void addFile(String name, long lengthBytes, in byte[] metadata);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 7a28022..f264adb 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -29,8 +29,6 @@
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.IIntentReceiver;
-import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager.DeleteFlags;
@@ -38,11 +36,9 @@
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.FileBridge;
 import android.os.Handler;
 import android.os.HandlerExecutor;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
@@ -71,8 +67,6 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.stream.Collectors;
 
@@ -182,9 +176,8 @@
      * {@link #STATUS_PENDING_USER_ACTION}, {@link #STATUS_SUCCESS},
      * {@link #STATUS_FAILURE}, {@link #STATUS_FAILURE_ABORTED},
      * {@link #STATUS_FAILURE_BLOCKED}, {@link #STATUS_FAILURE_CONFLICT},
-     * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID},
-     * {@link #STATUS_FAILURE_STORAGE}, {@link #STATUS_FAILURE_NAME_NOT_FOUND},
-     * {@link #STATUS_FAILURE_ILLEGAL_STATE} or {@link #STATUS_FAILURE_SECURITY}.
+     * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID}, or
+     * {@link #STATUS_FAILURE_STORAGE}.
      * <p>
      * More information about a status may be available through additional
      * extras; see the individual status documentation for details.
@@ -229,6 +222,19 @@
     public static final String EXTRA_CALLBACK = "android.content.pm.extra.CALLBACK";
 
     /**
+     * Type of DataLoader for this session. Will be one of
+     * {@link #DATA_LOADER_TYPE_NONE}, {@link #DATA_LOADER_TYPE_STREAMING},
+     * {@link #DATA_LOADER_TYPE_INCREMENTAL}.
+     * <p>
+     * See the individual types documentation for details.
+     *
+     * @see Intent#getIntExtra(String, int)
+     * {@hide}
+     */
+    @SystemApi
+    public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
+
+    /**
      * Streaming installation pending.
      * Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
      *
@@ -333,32 +339,31 @@
     public static final int STATUS_FAILURE_INCOMPATIBLE = 7;
 
     /**
-     * The transfer failed because a target package can't be found. For example
-     * transferring a session to a non-existing package.
-     * <p>
-     * The result may also contain {@link #EXTRA_OTHER_PACKAGE_NAME} with the
-     * missing package.
+     * Default value, non-streaming installation session.
      *
-     * @see #EXTRA_STATUS_MESSAGE
-     * @see #EXTRA_OTHER_PACKAGE_NAME
+     * @see #EXTRA_DATA_LOADER_TYPE
+     * {@hide}
      */
-    public static final int STATUS_FAILURE_NAME_NOT_FOUND = 8;
+    @SystemApi
+    public static final int DATA_LOADER_TYPE_NONE = DataLoaderType.NONE;
 
     /**
-     * The transfer failed because a session is in invalid state. For example
-     * transferring an already committed session.
+     * Streaming installation using data loader.
      *
-     * @see #EXTRA_STATUS_MESSAGE
+     * @see #EXTRA_DATA_LOADER_TYPE
+     * {@hide}
      */
-    public static final int STATUS_FAILURE_ILLEGAL_STATE = 9;
+    @SystemApi
+    public static final int DATA_LOADER_TYPE_STREAMING = DataLoaderType.STREAMING;
 
     /**
-     * The transfer failed for security reasons. For example transferring
-     * to a package which does not have INSTALL_PACKAGES permission.
+     * Streaming installation using Incremental FileSystem.
      *
-     * @see #EXTRA_STATUS_MESSAGE
+     * @see #EXTRA_DATA_LOADER_TYPE
+     * {@hide}
      */
-    public static final int STATUS_FAILURE_SECURITY = 10;
+    @SystemApi
+    public static final int DATA_LOADER_TYPE_INCREMENTAL = DataLoaderType.INCREMENTAL;
 
     private final IPackageInstaller mInstaller;
     private final int mUserId;
@@ -1143,8 +1148,7 @@
         }
 
         /**
-         * Attempt to commit a session that has been {@link #transfer(String, IntentSender)
-         * transferred}.
+         * Attempt to commit a session that has been {@link #transfer(String) transferred}.
          *
          * <p>If the device reboots before the session has been finalized, you may commit the
          * session again.
@@ -1185,43 +1189,6 @@
          *
          * @param packageName The package of the new owner. Needs to hold the INSTALL_PACKAGES
          *                    permission.
-         * @param statusReceiver Called when the state of the session changes. Intents sent to
-         *                       this receiver contain {@link #EXTRA_STATUS}. Possible statuses:
-         *                       {@link #STATUS_FAILURE_NAME_NOT_FOUND},
-         *                       {@link #STATUS_FAILURE_ILLEGAL_STATE},
-         *                       {@link #STATUS_FAILURE_SECURITY},
-         *                       {@link #STATUS_FAILURE}.
-         *                       Refer to the individual transfer status codes on how to handle
-         *                       them.
-         *
-         * @throws PackageManager.NameNotFoundException if the new owner could not be found.
-         * @throws SecurityException if called after the session has been committed or abandoned.
-         * @throws SecurityException if the session does not update the original installer
-         * @throws SecurityException if streams opened through
-         *                           {@link #openWrite(String, long, long) are still open.
-         */
-        public void transfer(@NonNull String packageName, @NonNull IntentSender statusReceiver)
-                throws PackageManager.NameNotFoundException {
-            Objects.requireNonNull(statusReceiver);
-            Objects.requireNonNull(packageName);
-
-            try {
-                mSession.transfer(packageName, statusReceiver);
-            } catch (ParcelableException e) {
-                e.maybeRethrow(PackageManager.NameNotFoundException.class);
-                throw new RuntimeException(e);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-
-        /**
-         * Transfer the session to a new owner.
-         * This is a convenience blocking wrapper around {@link #transfer(String, IntentSender)}.
-         * Converts all statuses into exceptions.
-         *
-         * @param packageName The package of the new owner. Needs to hold the INSTALL_PACKAGES
-         *                    permission.
          *
          * @throws PackageManager.NameNotFoundException if the new owner could not be found.
          * @throws SecurityException if called after the session has been committed or abandoned.
@@ -1233,43 +1200,13 @@
                 throws PackageManager.NameNotFoundException {
             Objects.requireNonNull(packageName);
 
-            CompletableFuture<Intent> intentFuture = new CompletableFuture<Intent>();
             try {
-                IIntentSender localSender = new IIntentSender.Stub() {
-                    @Override
-                    public void send(int code, Intent intent, String resolvedType,
-                            IBinder whitelistToken,
-                            IIntentReceiver finishedReceiver, String requiredPermission,
-                            Bundle options) {
-                        intentFuture.complete(intent);
-                    }
-                };
-                transfer(packageName, new IntentSender(localSender));
+                mSession.transfer(packageName);
             } catch (ParcelableException e) {
                 e.maybeRethrow(PackageManager.NameNotFoundException.class);
                 throw new RuntimeException(e);
-            }
-
-            try {
-                Intent intent = intentFuture.get();
-                final int status = intent.getIntExtra(EXTRA_STATUS, Integer.MIN_VALUE);
-                final String statusMessage = intent.getStringExtra(EXTRA_STATUS_MESSAGE);
-                switch (status) {
-                    case STATUS_SUCCESS:
-                        break;
-                    case STATUS_FAILURE_NAME_NOT_FOUND:
-                        throw new PackageManager.NameNotFoundException(statusMessage);
-                    case STATUS_FAILURE_ILLEGAL_STATE:
-                        throw new IllegalStateException(statusMessage);
-                    case STATUS_FAILURE_SECURITY:
-                        throw new SecurityException(statusMessage);
-                    default:
-                        throw new RuntimeException(statusMessage);
-                }
-            } catch (InterruptedException e) {
-                throw new RuntimeException(e);
-            } catch (ExecutionException e) {
-                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
         }
 
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 87acbc1..fd4c265 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -59,7 +59,6 @@
 import android.content.pm.PackageParserCacheHelper.WriteHelper;
 import android.content.pm.parsing.AndroidPackage;
 import android.content.pm.parsing.ApkParseUtils;
-import android.content.pm.parsing.ComponentParseUtils;
 import android.content.pm.parsing.PackageImpl;
 import android.content.pm.parsing.PackageInfoUtils;
 import android.content.pm.parsing.ParsedPackage;
@@ -4350,6 +4349,7 @@
         a.info.directBootAware = false;
         a.info.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
         a.info.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
+        a.info.preferMinimalPostProcessing = ActivityInfo.MINIMAL_POST_PROCESSING_DEFAULT;
         if (hardwareAccelerated) {
             a.info.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
         }
@@ -4564,6 +4564,10 @@
             a.info.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode,
                     ActivityInfo.COLOR_MODE_DEFAULT);
 
+            a.info.preferMinimalPostProcessing = sa.getBoolean(
+                    R.styleable.AndroidManifestActivity_preferMinimalPostProcessing,
+                    ActivityInfo.MINIMAL_POST_PROCESSING_DEFAULT);
+
             if (sa.getBoolean(R.styleable.AndroidManifestActivity_showWhenLocked, false)) {
                 a.info.flags |= ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
             }
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 00507e1..5f90b6c4 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -147,6 +147,28 @@
     public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 1 << 5;
 
     /**
+     * Constant corresponding to {@code camera} in
+     * the {@link android.R.attr#foregroundServiceType} attribute.
+     * Use the camera device or record video.
+     * For apps with <code>targetSdkVersion</code> {@link android.os.Build.VERSION_CODES#R} and
+     * above, a foreground service will not be able to access the camera if this type is not
+     * specified in the manifest and in
+     * {@link android.app.Service#startForeground(int, android.app.Notification, int)}.
+     */
+    public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 1 << 6;
+
+    /**
+     * Constant corresponding to {@code microphone} in
+     * the {@link android.R.attr#foregroundServiceType} attribute.
+     * Use the microphone device or record audio.
+     * For apps with <code>targetSdkVersion</code> {@link android.os.Build.VERSION_CODES#R} and
+     * above, a foreground service will not be able to access the microphone if this type is not
+     * specified in the manifest and in
+     * {@link android.app.Service#startForeground(int, android.app.Notification, int)}.
+     */
+    public static final int FOREGROUND_SERVICE_TYPE_MICROPHONE = 1 << 7;
+
+    /**
      * A special value indicates to use all types set in manifest file.
      */
     public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1;
@@ -166,6 +188,8 @@
             FOREGROUND_SERVICE_TYPE_LOCATION,
             FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE,
             FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION,
+            FOREGROUND_SERVICE_TYPE_CAMERA,
+            FOREGROUND_SERVICE_TYPE_MICROPHONE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ForegroundServiceType {}
diff --git a/core/java/android/content/pm/parsing/ApkParseUtils.java b/core/java/android/content/pm/parsing/ApkParseUtils.java
index 38d3137..9b069ac 100644
--- a/core/java/android/content/pm/parsing/ApkParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkParseUtils.java
@@ -2640,6 +2640,7 @@
         activity.directBootAware = false;
         activity.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
         activity.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
+        activity.preferMinimalPostProcessing = ActivityInfo.MINIMAL_POST_PROCESSING_DEFAULT;
         if (hardwareAccelerated) {
             activity.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
         }
diff --git a/core/java/android/content/pm/parsing/ComponentParseUtils.java b/core/java/android/content/pm/parsing/ComponentParseUtils.java
index 56ace5e..3846202a 100644
--- a/core/java/android/content/pm/parsing/ComponentParseUtils.java
+++ b/core/java/android/content/pm/parsing/ComponentParseUtils.java
@@ -553,6 +553,7 @@
         public String requestedVrComponent;
         public int rotationAnimation = -1;
         public int colorMode;
+        public boolean preferMinimalPostProcessing;
         public int order;
 
         public ActivityInfo.WindowLayout windowLayout;
@@ -640,6 +641,7 @@
             dest.writeString(this.requestedVrComponent);
             dest.writeInt(this.rotationAnimation);
             dest.writeInt(this.colorMode);
+            dest.writeBoolean(this.preferMinimalPostProcessing);
             dest.writeInt(this.order);
             dest.writeBundle(this.metaData);
 
@@ -685,6 +687,7 @@
             this.requestedVrComponent = in.readString();
             this.rotationAnimation = in.readInt();
             this.colorMode = in.readInt();
+            this.preferMinimalPostProcessing = in.readByte() != 0;
             this.order = in.readInt();
             this.metaData = in.readBundle();
             if (in.readInt() == 1) {
@@ -1645,6 +1648,10 @@
                 result.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode,
                         ActivityInfo.COLOR_MODE_DEFAULT);
 
+                result.preferMinimalPostProcessing = sa.getBoolean(
+                        R.styleable.AndroidManifestActivity_preferMinimalPostProcessing,
+                        ActivityInfo.MINIMAL_POST_PROCESSING_DEFAULT);
+
                 if (sa.getBoolean(R.styleable.AndroidManifestActivity_showWhenLocked, false)) {
                     result.flags |= ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
                 }
diff --git a/core/java/android/content/pm/parsing/PackageInfoUtils.java b/core/java/android/content/pm/parsing/PackageInfoUtils.java
index 73a8d2a..e0ba99b 100644
--- a/core/java/android/content/pm/parsing/PackageInfoUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoUtils.java
@@ -345,6 +345,7 @@
         ai.requestedVrComponent = a.requestedVrComponent;
         ai.rotationAnimation = a.rotationAnimation;
         ai.colorMode = a.colorMode;
+        ai.preferMinimalPostProcessing = a.preferMinimalPostProcessing;
         ai.windowLayout = a.windowLayout;
         ai.metaData = a.metaData;
         ai.applicationInfo = applicationInfo;
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index f722275..796cfdc 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -39,6 +39,8 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Map;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
 
 /**
  * Represents a SQLite database connection.
@@ -123,8 +125,10 @@
             boolean enableTrace, boolean enableProfile, int lookasideSlotSize,
             int lookasideSlotCount);
     private static native void nativeClose(long connectionPtr);
-    private static native void nativeRegisterCustomFunction(long connectionPtr,
-            SQLiteCustomFunction function);
+    private static native void nativeRegisterCustomScalarFunction(long connectionPtr,
+            String name, UnaryOperator<String> function);
+    private static native void nativeRegisterCustomAggregateFunction(long connectionPtr,
+            String name, BinaryOperator<String> function);
     private static native void nativeRegisterLocalizedCollators(long connectionPtr, String locale);
     private static native long nativePrepareStatement(long connectionPtr, String sql);
     private static native void nativeFinalizeStatement(long connectionPtr, long statementPtr);
@@ -225,13 +229,7 @@
         setJournalSizeLimit();
         setAutoCheckpointInterval();
         setLocaleFromConfiguration();
-
-        // Register custom functions.
-        final int functionCount = mConfiguration.customFunctions.size();
-        for (int i = 0; i < functionCount; i++) {
-            SQLiteCustomFunction function = mConfiguration.customFunctions.get(i);
-            nativeRegisterCustomFunction(mConnectionPtr, function);
-        }
+        setCustomFunctionsFromConfiguration();
     }
 
     private void dispose(boolean finalized) {
@@ -457,6 +455,19 @@
         }
     }
 
+    private void setCustomFunctionsFromConfiguration() {
+        for (int i = 0; i < mConfiguration.customScalarFunctions.size(); i++) {
+            nativeRegisterCustomScalarFunction(mConnectionPtr,
+                    mConfiguration.customScalarFunctions.keyAt(i),
+                    mConfiguration.customScalarFunctions.valueAt(i));
+        }
+        for (int i = 0; i < mConfiguration.customAggregateFunctions.size(); i++) {
+            nativeRegisterCustomAggregateFunction(mConnectionPtr,
+                    mConfiguration.customAggregateFunctions.keyAt(i),
+                    mConfiguration.customAggregateFunctions.valueAt(i));
+        }
+    }
+
     private void checkDatabaseWiped() {
         if (!SQLiteGlobal.checkDbWipe()) {
             return;
@@ -491,15 +502,6 @@
     void reconfigure(SQLiteDatabaseConfiguration configuration) {
         mOnlyAllowReadOnlyOperations = false;
 
-        // Register custom functions.
-        final int functionCount = configuration.customFunctions.size();
-        for (int i = 0; i < functionCount; i++) {
-            SQLiteCustomFunction function = configuration.customFunctions.get(i);
-            if (!mConfiguration.customFunctions.contains(function)) {
-                nativeRegisterCustomFunction(mConnectionPtr, function);
-            }
-        }
-
         // Remember what changed.
         boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
                 != mConfiguration.foreignKeyConstraintsEnabled;
@@ -507,6 +509,10 @@
                 & (SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING
                 | SQLiteDatabase.ENABLE_LEGACY_COMPATIBILITY_WAL)) != 0;
         boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
+        boolean customScalarFunctionsChanged = !configuration.customScalarFunctions
+                .equals(mConfiguration.customScalarFunctions);
+        boolean customAggregateFunctionsChanged = !configuration.customAggregateFunctions
+                .equals(mConfiguration.customAggregateFunctions);
 
         // Update configuration parameters.
         mConfiguration.updateParametersFrom(configuration);
@@ -514,20 +520,18 @@
         // Update prepared statement cache size.
         mPreparedStatementCache.resize(configuration.maxSqlCacheSize);
 
-        // Update foreign key mode.
         if (foreignKeyModeChanged) {
             setForeignKeyModeFromConfiguration();
         }
-
-        // Update WAL.
         if (walModeChanged) {
             setWalModeFromConfiguration();
         }
-
-        // Update locale.
         if (localeChanged) {
             setLocaleFromConfiguration();
         }
+        if (customScalarFunctionsChanged || customAggregateFunctionsChanged) {
+            setCustomFunctionsFromConfiguration();
+        }
     }
 
     // Called by SQLiteConnectionPool only.
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 44c78aa..458914e 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -62,6 +62,8 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.WeakHashMap;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
 
 /**
  * Exposes methods to manage a SQLite database.
@@ -958,26 +960,87 @@
     }
 
     /**
-     * Registers a CustomFunction callback as a function that can be called from
-     * SQLite database triggers.
+     * Register a custom scalar function that can be called from SQL
+     * expressions.
+     * <p>
+     * For example, registering a custom scalar function named {@code REVERSE}
+     * could be used in a query like
+     * {@code SELECT REVERSE(name) FROM employees}.
+     * <p>
+     * When attempting to register multiple functions with the same function
+     * name, SQLite will replace any previously defined functions with the
+     * latest definition, regardless of what function type they are. SQLite does
+     * not support unregistering functions.
      *
-     * @param name the name of the sqlite3 function
-     * @param numArgs the number of arguments for the function
-     * @param function callback to call when the function is executed
-     * @hide
+     * @param functionName Case-insensitive name to register this function
+     *            under, limited to 255 UTF-8 bytes in length.
+     * @param scalarFunction Functional interface that will be invoked when the
+     *            function name is used by a SQL statement. The argument values
+     *            from the SQL statement are passed to the functional interface,
+     *            and the return values from the functional interface are
+     *            returned back into the SQL statement.
+     * @throws SQLiteException if the custom function could not be registered.
+     * @see #setCustomAggregateFunction(String, BinaryOperator)
      */
-    public void addCustomFunction(String name, int numArgs, CustomFunction function) {
-        // Create wrapper (also validates arguments).
-        SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function);
+    public void setCustomScalarFunction(@NonNull String functionName,
+            @NonNull UnaryOperator<String> scalarFunction) throws SQLiteException {
+        Objects.requireNonNull(functionName);
+        Objects.requireNonNull(scalarFunction);
 
         synchronized (mLock) {
             throwIfNotOpenLocked();
 
-            mConfigurationLocked.customFunctions.add(wrapper);
+            mConfigurationLocked.customScalarFunctions.put(functionName, scalarFunction);
             try {
                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
             } catch (RuntimeException ex) {
-                mConfigurationLocked.customFunctions.remove(wrapper);
+                mConfigurationLocked.customScalarFunctions.remove(functionName);
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Register a custom aggregate function that can be called from SQL
+     * expressions.
+     * <p>
+     * For example, registering a custom aggregation function named
+     * {@code LONGEST} could be used in a query like
+     * {@code SELECT LONGEST(name) FROM employees}.
+     * <p>
+     * The implementation of this method follows the reduction flow outlined in
+     * {@link java.util.stream.Stream#reduce(BinaryOperator)}, and the custom
+     * aggregation function is expected to be an associative accumulation
+     * function, as defined by that class.
+     * <p>
+     * When attempting to register multiple functions with the same function
+     * name, SQLite will replace any previously defined functions with the
+     * latest definition, regardless of what function type they are. SQLite does
+     * not support unregistering functions.
+     *
+     * @param functionName Case-insensitive name to register this function
+     *            under, limited to 255 UTF-8 bytes in length.
+     * @param aggregateFunction Functional interface that will be invoked when
+     *            the function name is used by a SQL statement. The argument
+     *            values from the SQL statement are passed to the functional
+     *            interface, and the return values from the functional interface
+     *            are returned back into the SQL statement.
+     * @throws SQLiteException if the custom function could not be registered.
+     * @see #setCustomScalarFunction(String, UnaryOperator)
+     */
+    public void setCustomAggregateFunction(@NonNull String functionName,
+            @NonNull BinaryOperator<String> aggregateFunction) throws SQLiteException {
+        Objects.requireNonNull(functionName);
+        Objects.requireNonNull(aggregateFunction);
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            mConfigurationLocked.customAggregateFunctions.put(functionName, aggregateFunction);
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.customAggregateFunctions.remove(functionName);
                 throw ex;
             }
         }
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 6a52b72..b11942a 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -17,9 +17,12 @@
 package android.database.sqlite;
 
 import android.compat.annotation.UnsupportedAppUsage;
+import android.util.ArrayMap;
 
-import java.util.ArrayList;
 import java.util.Locale;
+import java.util.Map;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
 import java.util.regex.Pattern;
 
 /**
@@ -87,10 +90,16 @@
     public boolean foreignKeyConstraintsEnabled;
 
     /**
-     * The custom functions to register.
+     * The custom scalar functions to register.
      */
-    public final ArrayList<SQLiteCustomFunction> customFunctions =
-            new ArrayList<SQLiteCustomFunction>();
+    public final ArrayMap<String, UnaryOperator<String>> customScalarFunctions
+            = new ArrayMap<>();
+
+    /**
+     * The custom aggregate functions to register.
+     */
+    public final ArrayMap<String, BinaryOperator<String>> customAggregateFunctions
+            = new ArrayMap<>();
 
     /**
      * The size in bytes of each lookaside slot
@@ -181,8 +190,10 @@
         maxSqlCacheSize = other.maxSqlCacheSize;
         locale = other.locale;
         foreignKeyConstraintsEnabled = other.foreignKeyConstraintsEnabled;
-        customFunctions.clear();
-        customFunctions.addAll(other.customFunctions);
+        customScalarFunctions.clear();
+        customScalarFunctions.putAll(other.customScalarFunctions);
+        customAggregateFunctions.clear();
+        customAggregateFunctions.putAll(other.customAggregateFunctions);
         lookasideSlotSize = other.lookasideSlotSize;
         lookasideSlotCount = other.lookasideSlotCount;
         idleConnectionTimeoutMs = other.idleConnectionTimeoutMs;
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index a695ce8..c686624 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -36,6 +36,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.security.identity.IdentityCredential;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -555,6 +556,10 @@
             super(mac);
         }
 
+        public CryptoObject(@NonNull IdentityCredential credential) {
+            super(credential);
+        }
+
         /**
          * Get {@link Signature} object.
          * @return {@link Signature} object or null if this doesn't contain one.
@@ -578,6 +583,14 @@
         public Mac getMac() {
             return super.getMac();
         }
+
+        /**
+         * Get {@link IdentityCredential} object.
+         * @return {@link IdentityCredential} object or null if this doesn't contain one.
+         */
+        public @Nullable IdentityCredential getIdentityCredential() {
+            return super.getIdentityCredential();
+        }
     }
 
     /**
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 787dc66..0af18df 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -17,6 +17,7 @@
 package android.hardware.biometrics;
 
 import android.annotation.NonNull;
+import android.security.identity.IdentityCredential;
 import android.security.keystore.AndroidKeyStoreProvider;
 
 import java.security.Signature;
@@ -26,7 +27,8 @@
 
 /**
  * A wrapper class for the crypto objects supported by BiometricPrompt and FingerprintManager.
- * Currently the framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
+ * Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac} and
+ * {@link IdentityCredential} objects.
  * @hide
  */
 public class CryptoObject {
@@ -44,6 +46,10 @@
         mCrypto = mac;
     }
 
+    public CryptoObject(@NonNull IdentityCredential credential) {
+        mCrypto = credential;
+    }
+
     /**
      * Get {@link Signature} object.
      * @return {@link Signature} object or null if this doesn't contain one.
@@ -69,11 +75,23 @@
     }
 
     /**
+     * Get {@link IdentityCredential} object.
+     * @return {@link IdentityCredential} object or null if this doesn't contain one.
+     */
+    public IdentityCredential getIdentityCredential() {
+        return mCrypto instanceof IdentityCredential ? (IdentityCredential) mCrypto : null;
+    }
+
+    /**
      * @hide
      * @return the opId associated with this object or 0 if none
      */
     public final long getOpId() {
-        return mCrypto != null
-                ? AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCrypto) : 0;
+        if (mCrypto == null) {
+            return 0;
+        } else if (mCrypto instanceof IdentityCredential) {
+            return ((IdentityCredential) mCrypto).getCredstoreOperationHandle();
+        }
+        return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCrypto);
     }
 };
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index fb5f136..d67de09 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -749,6 +749,17 @@
         return mGlobal.getDefaultBrightnessConfiguration();
     }
 
+
+    /**
+     * Gets the last requested minimal post processing setting for the display with displayId.
+     *
+     * @hide
+     */
+    @TestApi
+    public boolean isMinimalPostProcessingRequested(int displayId) {
+        return mGlobal.isMinimalPostProcessingRequested(displayId);
+    }
+
     /**
      * Temporarily sets the brightness of the display.
      * <p>
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 2a58495..fd539e8 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -594,6 +594,19 @@
     }
 
     /**
+     * Gets the last requested minimal post processing setting for the display with displayId.
+     *
+     * @hide
+     */
+    public boolean isMinimalPostProcessingRequested(int displayId) {
+        try {
+            return mDm.isMinimalPostProcessingRequested(displayId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Temporarily sets the brightness of the display.
      * <p>
      * Requires the {@link android.Manifest.permission#CONTROL_DISPLAY_BRIGHTNESS} permission.
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index 0143c91..ccf221b 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -111,6 +111,9 @@
     // Gets the default brightness configuration if configured.
     BrightnessConfiguration getDefaultBrightnessConfiguration();
 
+    // Gets the last requested minimal post processing settings for display with displayId.
+    boolean isMinimalPostProcessingRequested(int displayId);
+
     // Temporarily sets the display brightness.
     void setTemporaryBrightness(int brightness);
 
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 7bc4529..ff9d145 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -44,6 +44,7 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.security.identity.IdentityCredential;
 import android.util.Slog;
 
 import java.security.Signature;
@@ -125,6 +126,10 @@
             super(mac);
         }
 
+        public CryptoObject(@NonNull IdentityCredential credential) {
+            super(credential);
+        }
+
         /**
          * Get {@link Signature} object.
          * @return {@link Signature} object or null if this doesn't contain one.
@@ -148,6 +153,14 @@
         public Mac getMac() {
             return super.getMac();
         }
+
+        /**
+         * Get {@link IdentityCredential} object.
+         * @return {@link IdentityCredential} object or null if this doesn't contain one.
+         */
+        public @Nullable IdentityCredential getIdentityCredential() {
+            return super.getIdentityCredential();
+        }
     }
 
     /**
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index aae9fd4..7cc78f7 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -33,6 +33,7 @@
 import com.android.internal.util.Protocol;
 
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -50,20 +51,29 @@
     /**
      * The {@link Network} corresponding to this object.
      */
-    @NonNull
-    public final Network network;
+    @Nullable
+    private volatile Network mNetwork;
+
+    // Whether this NetworkAgent is using the legacy (never unhidden) API. The difference is
+    // that the legacy API uses NetworkInfo to convey the state, while the current API is
+    // exposing methods to manage it and generate it internally instead.
+    // TODO : remove this as soon as all agents have been converted.
+    private final boolean mIsLegacy;
 
     private final Handler mHandler;
     private volatile AsyncChannel mAsyncChannel;
     private final String LOG_TAG;
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
-    private final Context mContext;
     private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
     private volatile long mLastBwRefreshTime = 0;
     private static final long BW_REFRESH_MIN_WIN_MS = 500;
     private boolean mBandwidthUpdateScheduled = false;
     private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false);
+    // Not used by legacy agents. Non-legacy agents use this to convert the NetworkAgent system API
+    // into the internal API of ConnectivityService.
+    @NonNull
+    private NetworkInfo mNetworkInfo;
 
     /**
      * The ID of the {@link NetworkProvider} that created this object, or
@@ -262,46 +272,96 @@
      */
     public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
 
-    // TODO : remove these two constructors. They are a stopgap measure to help sheperding a number
-    // of dependent changes that would conflict throughout the automerger graph. Having these
-    // temporarily helps with the process of going through with all these dependent changes across
-    // the entire tree.
-    /** @hide TODO: decide which of these to expose. */
+    /** @hide TODO: remove and replace usage with the public constructor. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
         this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE);
+        // Register done by the constructor called in the previous line
     }
 
-    /** @hide TODO: decide which of these to expose. */
+    /** @hide TODO: remove and replace usage with the public constructor. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) {
         this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE);
+        // Register done by the constructor called in the previous line
     }
 
-    /** @hide TODO: decide which of these to expose. */
+    /** @hide TODO: remove and replace usage with the public constructor. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, int providerId) {
         this(looper, context, logTag, ni, nc, lp, score, null, providerId);
+        // Register done by the constructor called in the previous line
     }
 
-    /** @hide TODO: decide which of these to expose. */
+    /** @hide TODO: remove and replace usage with the public constructor. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config,
             int providerId) {
+        this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */);
+        register();
+    }
+
+    private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
+        // The subtype can be changed with (TODO) setLegacySubtype, but it starts
+        // with the type and an empty description.
+        return new NetworkInfo(config.legacyType, config.legacyType, config.legacyTypeName, "");
+    }
+
+    /**
+     * Create a new network agent.
+     * @param context a {@link Context} to get system services from.
+     * @param looper the {@link Looper} on which to invoke the callbacks.
+     * @param logTag the tag for logs
+     * @param nc the initial {@link NetworkCapabilities} of this network. Update with
+     *           sendNetworkCapabilities.
+     * @param lp the initial {@link LinkProperties} of this network. Update with sendLinkProperties.
+     * @param score the initial score of this network. Update with sendNetworkScore.
+     * @param config an immutable {@link NetworkAgentConfig} for this agent.
+     * @param provider the {@link NetworkProvider} managing this agent.
+     */
+    public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
+            @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
+        this(looper, context, logTag, nc, lp, score, config,
+                provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
+                getLegacyNetworkInfo(config), false /* legacy */);
+    }
+
+    private static class InitialConfiguration {
+        public final Context context;
+        public final NetworkCapabilities capabilities;
+        public final LinkProperties properties;
+        public final int score;
+        public final NetworkAgentConfig config;
+        public final NetworkInfo info;
+        InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
+                @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config,
+                @NonNull NetworkInfo info) {
+            this.context = context;
+            this.capabilities = capabilities;
+            this.properties = properties;
+            this.score = score;
+            this.config = config;
+            this.info = info;
+        }
+    }
+    private volatile InitialConfiguration mInitialConfiguration;
+
+    private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
+            @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni,
+            boolean legacy) {
         mHandler = new NetworkAgentHandler(looper);
         LOG_TAG = logTag;
-        mContext = context;
+        mIsLegacy = legacy;
+        mNetworkInfo = new NetworkInfo(ni);
         this.providerId = providerId;
         if (ni == null || nc == null || lp == null) {
             throw new IllegalArgumentException();
         }
 
-        if (VDBG) log("Registering NetworkAgent");
-        ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        network = cm.registerNetworkAgent(new Messenger(mHandler), new NetworkInfo(ni),
-                new LinkProperties(lp), new NetworkCapabilities(nc), score, config,
-                providerId);
+        mInitialConfiguration = new InitialConfiguration(context, new NetworkCapabilities(nc),
+                new LinkProperties(lp), score, config, ni);
     }
 
     private class NetworkAgentHandler extends Handler {
@@ -423,6 +483,32 @@
         }
     }
 
+    /**
+     * Register this network agent with ConnectivityService.
+     * @return the Network associated with this network agent (which can also be obtained later
+     *         by calling getNetwork() on this agent).
+     */
+    @NonNull
+    public Network register() {
+        if (VDBG) log("Registering NetworkAgent");
+        final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        mNetwork = cm.registerNetworkAgent(new Messenger(mHandler),
+                new NetworkInfo(mInitialConfiguration.info),
+                mInitialConfiguration.properties, mInitialConfiguration.capabilities,
+                mInitialConfiguration.score, mInitialConfiguration.config, providerId);
+        mInitialConfiguration = null; // All this memory can now be GC'd
+        return mNetwork;
+    }
+
+    /**
+     * @return The Network associated with this agent, or null if it's not registered yet.
+     */
+    @Nullable
+    public Network getNetwork() {
+        return mNetwork;
+    }
+
     private void queueOrSendMessage(int what, Object obj) {
         queueOrSendMessage(what, 0, 0, obj);
     }
@@ -455,15 +541,89 @@
      * @param linkProperties the new LinkProperties.
      */
     public void sendLinkProperties(@NonNull LinkProperties linkProperties) {
+        Objects.requireNonNull(linkProperties);
         queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
     }
 
     /**
+     * Inform ConnectivityService that this agent has now connected.
+     */
+    public void setConnected() {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException(
+                    "Legacy agents can't call setConnected.");
+        }
+        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
+     * Unregister this network agent.
+     *
+     * This signals the network has disconnected and ends its lifecycle. After this is called,
+     * the network is torn down and this agent can no longer be used.
+     */
+    public void unregister() {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException(
+                    "Legacy agents can't call unregister.");
+        }
+        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
+     * Change the legacy subtype of this network agent.
+     *
+     * This is only for backward compatibility and should not be used by non-legacy network agents,
+     * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use
+     * this and others will be thrown an exception if they try.
+     *
+     * @deprecated this is for backward compatibility only.
+     * @param legacySubtype the legacy subtype.
+     */
+    @Deprecated
+    public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException("Legacy agents can't call setLegacySubtype.");
+        }
+        mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
+     * Set the ExtraInfo of this network agent.
+     *
+     * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the
+     * broadcasts about the corresponding Network.
+     * This is only for backward compatibility and should not be used by non-legacy network agents,
+     * who will be thrown an exception if they try. The extra info should only be :
+     * <ul>
+     *   <li>For cellular agents, the APN name.</li>
+     *   <li>For ethernet agents, the interface name.</li>
+     * </ul>
+     *
+     * @deprecated this is for backward compatibility only.
+     * @param extraInfo the ExtraInfo.
+     */
+    @Deprecated
+    public void setLegacyExtraInfo(@Nullable final String extraInfo) {
+        if (mIsLegacy) {
+            throw new UnsupportedOperationException("Legacy agents can't call setLegacyExtraInfo.");
+        }
+        mNetworkInfo.setExtraInfo(extraInfo);
+        queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+    }
+
+    /**
      * Must be called by the agent when it has a new NetworkInfo object.
      * @hide TODO: expose something better.
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void sendNetworkInfo(NetworkInfo networkInfo) {
+        if (!mIsLegacy) {
+            throw new UnsupportedOperationException("Only legacy agents can call sendNetworkInfo.");
+        }
         queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
     }
 
@@ -472,6 +632,7 @@
      * @param networkCapabilities the new NetworkCapabilities.
      */
     public void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
+        Objects.requireNonNull(networkCapabilities);
         mBandwidthUpdatePending.set(false);
         mLastBwRefreshTime = System.currentTimeMillis();
         queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java
index abc6b67..7e2db4a 100644
--- a/core/java/android/net/NetworkAgentConfig.java
+++ b/core/java/android/net/NetworkAgentConfig.java
@@ -21,12 +21,12 @@
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
+
+import java.util.Objects;
 
 /**
  * Allows a network transport to provide the system with policy and configuration information about
- * a particular network when registering a {@link NetworkAgent}. This information cannot change once
- * the agent is registered.
+ * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
  *
  * @hide
  */
@@ -54,23 +54,47 @@
     public boolean explicitlySelected;
 
     /**
+     * @return whether this network was explicitly selected by the user.
+     */
+    public boolean isExplicitlySelected() {
+        return explicitlySelected;
+    }
+
+    /**
      * Set if the user desires to use this network even if it is unvalidated. This field has meaning
      * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
      * appropriate value based on previous user choice.
      *
+     * TODO : rename this field to match its accessor
      * @hide
      */
     public boolean acceptUnvalidated;
 
     /**
+     * @return whether the system should accept this network even if it doesn't validate.
+     */
+    public boolean isUnvalidatedConnectivityAcceptable() {
+        return acceptUnvalidated;
+    }
+
+    /**
      * Whether the user explicitly set that this network should be validated even if presence of
      * only partial internet connectivity.
      *
+     * TODO : rename this field to match its accessor
      * @hide
      */
     public boolean acceptPartialConnectivity;
 
     /**
+     * @return whether the system should validate this network even if it only offers partial
+     *     Internet connectivity.
+     */
+    public boolean isPartialConnectivityAcceptable() {
+        return acceptPartialConnectivity;
+    }
+
+    /**
      * Set to avoid surfacing the "Sign in to network" notification.
      * if carrier receivers/apps are registered to handle the carrier-specific provisioning
      * procedure, a carrier specific provisioning notification will be placed.
@@ -120,12 +144,42 @@
     }
 
     /**
+     * The legacy type of this network agent, or TYPE_NONE if unset.
+     * @hide
+     */
+    public int legacyType = ConnectivityManager.TYPE_NONE;
+
+    /**
+     * @return the legacy type
+     */
+    public int getLegacyType() {
+        return legacyType;
+    }
+
+    /**
      * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
      * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
      *
+     * This is not parceled, because it would not make sense.
+     *
      * @hide
      */
-    public boolean hasShownBroken;
+    public transient boolean hasShownBroken;
+
+    /**
+     * The name of the legacy network type. It's a free-form string used in logging.
+     * @hide
+     */
+    @NonNull
+    public String legacyTypeName = "";
+
+    /**
+     * @return the name of the legacy network type. It's a free-form string used in logging.
+     */
+    @NonNull
+    public String getLegacyTypeName() {
+        return legacyTypeName;
+    }
 
     /** @hide */
     public NetworkAgentConfig() {
@@ -137,9 +191,12 @@
             allowBypass = nac.allowBypass;
             explicitlySelected = nac.explicitlySelected;
             acceptUnvalidated = nac.acceptUnvalidated;
+            acceptPartialConnectivity = nac.acceptPartialConnectivity;
             subscriberId = nac.subscriberId;
             provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
             skip464xlat = nac.skip464xlat;
+            legacyType = nac.legacyType;
+            legacyTypeName = nac.legacyTypeName;
         }
     }
 
@@ -150,6 +207,43 @@
         private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
 
         /**
+         * Sets whether the network was explicitly selected by the user.
+         *
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setExplicitlySelected(final boolean explicitlySelected) {
+            mConfig.explicitlySelected = explicitlySelected;
+            return this;
+        }
+
+        /**
+         * Sets whether the system should validate this network even if it is found not to offer
+         * Internet connectivity.
+         *
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setUnvalidatedConnectivityAcceptable(
+                final boolean unvalidatedConnectivityAcceptable) {
+            mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
+            return this;
+        }
+
+        /**
+         * Sets whether the system should validate this network even if it is found to only offer
+         * partial Internet connectivity.
+         *
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setPartialConnectivityAcceptable(
+                final boolean partialConnectivityAcceptable) {
+            mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
+            return this;
+        }
+
+        /**
          * Sets the subscriber ID for this network.
          *
          * @return this builder, to facilitate chaining.
@@ -185,6 +279,29 @@
         }
 
         /**
+         * Sets the legacy type for this network.
+         *
+         * @param legacyType the type
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setLegacyType(int legacyType) {
+            mConfig.legacyType = legacyType;
+            return this;
+        }
+
+        /**
+         * Sets the name of the legacy type of the agent. It's a free-form string used in logging.
+         * @param legacyTypeName the name
+         * @return this builder, to facilitate chaining.
+         */
+        @NonNull
+        public Builder setLegacyTypeName(@NonNull String legacyTypeName) {
+            mConfig.legacyTypeName = legacyTypeName;
+            return this;
+        }
+
+        /**
          * Returns the constructed {@link NetworkAgentConfig} object.
          */
         @NonNull
@@ -194,6 +311,45 @@
     }
 
     @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        final NetworkAgentConfig that = (NetworkAgentConfig) o;
+        return allowBypass == that.allowBypass
+                && explicitlySelected == that.explicitlySelected
+                && acceptUnvalidated == that.acceptUnvalidated
+                && acceptPartialConnectivity == that.acceptPartialConnectivity
+                && provisioningNotificationDisabled == that.provisioningNotificationDisabled
+                && skip464xlat == that.skip464xlat
+                && legacyType == that.legacyType
+                && Objects.equals(subscriberId, that.subscriberId)
+                && Objects.equals(legacyTypeName, that.legacyTypeName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
+                acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
+                skip464xlat, legacyType, legacyTypeName);
+    }
+
+    @Override
+    public String toString() {
+        return "NetworkAgentConfig {"
+                + " allowBypass = " + allowBypass
+                + ", explicitlySelected = " + explicitlySelected
+                + ", acceptUnvalidated = " + acceptUnvalidated
+                + ", acceptPartialConnectivity = " + acceptPartialConnectivity
+                + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
+                + ", subscriberId = '" + subscriberId + '\''
+                + ", skip464xlat = " + skip464xlat
+                + ", legacyType = " + legacyType
+                + ", hasShownBroken = " + hasShownBroken
+                + ", legacyTypeName = '" + legacyTypeName + '\''
+                + "}";
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -203,9 +359,12 @@
         out.writeInt(allowBypass ? 1 : 0);
         out.writeInt(explicitlySelected ? 1 : 0);
         out.writeInt(acceptUnvalidated ? 1 : 0);
+        out.writeInt(acceptPartialConnectivity ? 1 : 0);
         out.writeString(subscriberId);
         out.writeInt(provisioningNotificationDisabled ? 1 : 0);
         out.writeInt(skip464xlat ? 1 : 0);
+        out.writeInt(legacyType);
+        out.writeString(legacyTypeName);
     }
 
     public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
@@ -216,9 +375,12 @@
             networkAgentConfig.allowBypass = in.readInt() != 0;
             networkAgentConfig.explicitlySelected = in.readInt() != 0;
             networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
+            networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
             networkAgentConfig.subscriberId = in.readString();
             networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
             networkAgentConfig.skip464xlat = in.readInt() != 0;
+            networkAgentConfig.legacyType = in.readInt();
+            networkAgentConfig.legacyTypeName = in.readString();
             return networkAgentConfig;
         }
 
diff --git a/core/java/android/os/ISystemConfig.aidl b/core/java/android/os/ISystemConfig.aidl
new file mode 100644
index 0000000..d3b0298
--- /dev/null
+++ b/core/java/android/os/ISystemConfig.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+  * Binder interface to query SystemConfig in the system server.
+  * {@hide}
+  */
+interface ISystemConfig {
+    /**
+     * @see SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierApps
+     */
+    List<String> getDisabledUntilUsedPreinstalledCarrierApps();
+
+    /**
+     * @see SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierAssociatedApps
+     */
+    Map getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+}
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index edaaf81..b10abe7 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -41,11 +41,11 @@
      * END OF DO NOT MOVE
      */
 
-    UserInfo createUser(in String name, in String userType, int flags);
-    UserInfo preCreateUser(in String userType);
-    UserInfo createProfileForUser(in String name, in String userType, int flags, int userId,
+    UserInfo createUserWithThrow(in String name, in String userType, int flags);
+    UserInfo preCreateUserWithThrow(in String userType);
+    UserInfo createProfileForUserWithThrow(in String name, in String userType, int flags, int userId,
             in String[] disallowedPackages);
-    UserInfo createRestrictedProfile(String name, int parentUserHandle);
+    UserInfo createRestrictedProfileWithThrow(String name, int parentUserHandle);
     void setUserEnabled(int userId);
     void setUserAdmin(int userId);
     void evictCredentialEncryptionKey(int userId);
@@ -100,7 +100,7 @@
     boolean isManagedProfile(int userId);
     boolean isDemoUser(int userId);
     boolean isPreCreated(int userId);
-    UserInfo createProfileForUserEvenWhenDisallowed(in String name, in String userType, int flags,
+    UserInfo createProfileForUserEvenWhenDisallowedWithThrow(in String name, in String userType, int flags,
             int userId, in String[] disallowedPackages);
     boolean isUserUnlockingOrUnlocked(int userId);
     int getUserIconBadgeResId(int userId);
@@ -113,7 +113,7 @@
     boolean isUserRunning(int userId);
     boolean isUserNameSet(int userId);
     boolean hasRestrictedProfiles();
-    boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target);
+    boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags);
     String getUserName();
     long getUserStartRealtime();
     long getUserUnlockRealtime();
diff --git a/core/java/android/os/SystemConfigManager.java b/core/java/android/os/SystemConfigManager.java
new file mode 100644
index 0000000..3a9ce2f
--- /dev/null
+++ b/core/java/android/os/SystemConfigManager.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.os;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Allows apps outside the system process to access various bits of configuration defined in
+ * /etc/sysconfig and its counterparts on OEM and vendor partitions.
+ *
+ * TODO: Intended for access by system mainline modules only. Marking as SystemApi until the
+ * module-only API surface is available.
+ * @hide
+ */
+@SystemApi
+@TestApi
+@SystemService(Context.SYSTEM_CONFIG_SERVICE)
+public class SystemConfigManager {
+    private static final String TAG = SystemConfigManager.class.getSimpleName();
+
+    private final ISystemConfig mInterface;
+
+    /** @hide **/
+    public SystemConfigManager() {
+        mInterface = ISystemConfig.Stub.asInterface(
+                ServiceManager.getService(Context.SYSTEM_CONFIG_SERVICE));
+    }
+
+    /**
+     * Returns a set of package names for carrier apps that are preinstalled on the device but
+     * should be disabled until the matching carrier's SIM is inserted into the device.
+     * @return A set of package names.
+     */
+    @RequiresPermission(Manifest.permission.READ_CARRIER_APP_INFO)
+    public @NonNull Set<String> getDisabledUntilUsedPreinstalledCarrierApps() {
+        try {
+            List<String> apps = mInterface.getDisabledUntilUsedPreinstalledCarrierApps();
+            return new ArraySet<>(apps);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Caught remote exception");
+            return Collections.emptySet();
+        }
+    }
+
+    /**
+     * Returns a map that describes helper apps associated with carrier apps that, like the apps
+     * returned by {@link #getDisabledUntilUsedPreinstalledCarrierApps()}, should be disabled until
+     * the correct SIM is inserted into the device.
+     * @return A map with keys corresponding to package names returned by
+     *         {@link #getDisabledUntilUsedPreinstalledCarrierApps()} and values as lists of package
+     *         names of helper apps.
+     */
+    @RequiresPermission(Manifest.permission.READ_CARRIER_APP_INFO)
+    public @NonNull Map<String, List<String>>
+            getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
+        try {
+            return (Map<String, List<String>>)
+                    mInterface.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Caught remote exception");
+            return Collections.emptyMap();
+        }
+    }
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2eaefca..08e4c3a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -28,6 +28,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UserHandleAware;
 import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
 import android.app.Activity;
@@ -50,6 +51,7 @@
 import android.location.LocationManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
+import android.util.AndroidException;
 import android.view.WindowManager.LayoutParams;
 
 import com.android.internal.R;
@@ -77,8 +79,12 @@
     private static final String TAG = "UserManager";
     @UnsupportedAppUsage
     private final IUserManager mService;
+    /** Holding the Application context (not constructor param context). */
     private final Context mContext;
 
+    /** The userId of the constructor param context. To be used instead of mContext.getUserId(). */
+    private final @UserIdInt int mUserId;
+
     private Boolean mIsManagedProfileCached;
     private Boolean mIsProfileCached;
 
@@ -87,6 +93,7 @@
      * This type of user cannot be created; it can only pre-exist on first boot.
      * @hide
      */
+    @SystemApi
     public static final String USER_TYPE_FULL_SYSTEM = "android.os.usertype.full.SYSTEM";
 
     /**
@@ -95,6 +102,7 @@
      * This is sometimes called an ordinary 'secondary user'.
      * @hide
      */
+    @SystemApi
     public static final String USER_TYPE_FULL_SECONDARY = "android.os.usertype.full.SECONDARY";
 
     /**
@@ -122,6 +130,7 @@
      * The intended purpose is for work profiles, which are managed by a corporate entity.
      * @hide
      */
+    @SystemApi
     public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED";
 
     /**
@@ -130,9 +139,26 @@
      * This type of user cannot be created; it can only pre-exist on first boot.
      * @hide
      */
+    @SystemApi
     public static final String USER_TYPE_SYSTEM_HEADLESS = "android.os.usertype.system.HEADLESS";
 
     /**
+     * Flag passed to {@link #requestQuietModeEnabled} to request disabling quiet mode only if
+     * there is no need to confirm the user credentials. If credentials are required to disable
+     * quiet mode, {@link #requestQuietModeEnabled} will do nothing and return {@code false}.
+     */
+    public static final int QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED = 0x1;
+
+    /**
+     * List of flags available for the {@link #requestQuietModeEnabled} method.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = { "QUIET_MODE_" }, value = {
+            QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED })
+    public @interface QuietModeFlag {}
+
+    /**
      * @hide
      * No user restriction.
      */
@@ -1419,6 +1445,62 @@
         public @UserOperationResult int getUserOperationResult() {
             return mUserOperationResult;
         }
+
+        /**
+         * Returns a UserOperationException containing the same message and error code.
+         * @hide
+         */
+        public static UserOperationException from(ServiceSpecificException exception) {
+            return new UserOperationException(exception.getMessage(), exception.errorCode);
+        }
+    }
+
+    /**
+     * Converts the ServiceSpecificException into a UserOperationException or throws null;
+     *
+     * @param exception exception to convert.
+     * @param throwInsteadOfNull if an exception should be thrown or null returned.
+     * @return null if chosen not to throw exception.
+     * @throws UserOperationException
+     */
+    private <T> T returnNullOrThrowUserOperationException(ServiceSpecificException exception,
+            boolean throwInsteadOfNull) throws UserOperationException {
+        if (throwInsteadOfNull) {
+            throw UserOperationException.from(exception);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Thrown to indicate user operation failed. (Checked exception)
+     * @hide
+     */
+    public static class CheckedUserOperationException extends AndroidException {
+        private final @UserOperationResult int mUserOperationResult;
+
+        /**
+         * Constructs a CheckedUserOperationException with specific result code.
+         *
+         * @param message the detail message
+         * @param userOperationResult the result code
+         * @hide
+         */
+        public CheckedUserOperationException(String message,
+                @UserOperationResult int userOperationResult) {
+            super(message);
+            mUserOperationResult = userOperationResult;
+        }
+
+        /** Returns the operation result code. */
+        public @UserOperationResult int getUserOperationResult() {
+            return mUserOperationResult;
+        }
+
+        /** Return a ServiceSpecificException containing the same message and error code. */
+        public ServiceSpecificException toServiceSpecificException() {
+            return new ServiceSpecificException(mUserOperationResult, getMessage());
+        }
     }
 
     /** @hide */
@@ -1431,6 +1513,7 @@
     public UserManager(Context context, IUserManager service) {
         mService = service;
         mContext = context.getApplicationContext();
+        mUserId = context.getUserId();
     }
 
     /**
@@ -1570,17 +1653,25 @@
     }
 
     /**
-     * Returns the user name of the user making this call.  This call is only
-     * available to applications on the system image; it requires the
-     * {@code android.permission.MANAGE_USERS} or {@code android.permission.GET_ACCOUNTS_PRIVILEGED}
-     * permissions.
+     * Returns the user name of the context user. This call is only available to applications on
+     * the system image; it requires the {@code android.permission.MANAGE_USERS} or {@code
+     * android.permission.GET_ACCOUNTS_PRIVILEGED} permissions.
+     *
      * @return the user name
      */
-    public String getUserName() {
-        try {
-            return mService.getUserName();
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}, conditional = true)
+    @UserHandleAware
+    public @NonNull String getUserName() {
+        if (UserHandle.myUserId() == mUserId) {
+            try {
+                return mService.getUserName();
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        } else {
+            UserInfo userInfo = getUserInfo(mUserId);
+            return userInfo == null ? "" : userInfo.name;
         }
     }
 
@@ -1623,7 +1714,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isPrimaryUser() {
         UserInfo user = getUserInfo(UserHandle.myUserId());
         return user != null && user.isPrimary();
@@ -1660,22 +1752,26 @@
      * user.
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isUserAdmin(@UserIdInt int userId) {
         UserInfo user = getUserInfo(userId);
         return user != null && user.isAdmin();
     }
 
     /**
-     * Returns whether the current user is of the given user type, such as
+     * Returns whether the context user's user is of the given user type, such as
      * {@link UserManager#USER_TYPE_FULL_GUEST}.
      *
      * @return true if the user is of the given user type.
      * @hide
      */
+    @SystemApi
+    @UserHandleAware
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean isUserOfType(@NonNull String userType) {
         try {
-            return mService.isUserOfType(UserHandle.myUserId(), userType);
+            return mService.isUserOfType(mUserId, userType);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -1691,6 +1787,7 @@
      * @return true if the userHandle user is of type userType
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean isUserOfType(@NonNull UserHandle userHandle, @NonNull String userType) {
         try {
@@ -1770,7 +1867,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isRestrictedProfile(@NonNull UserHandle user) {
         try {
             return mService.getUserInfo(user.getIdentifier()).isRestricted();
@@ -1783,6 +1881,7 @@
      * Checks if specified user can have restricted profile.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean canHaveRestrictedProfile(@UserIdInt int userId) {
         try {
             return mService.canHaveRestrictedProfile(userId);
@@ -1797,6 +1896,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean hasRestrictedProfiles() {
         try {
             return mService.hasRestrictedProfiles();
@@ -1811,6 +1911,8 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isGuestUser(@UserIdInt int userId) {
         UserInfo user = getUserInfo(userId);
         return user != null && user.isGuest();
@@ -1823,7 +1925,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isGuestUser() {
         UserInfo user = getUserInfo(UserHandle.myUserId());
         return user != null && user.isGuest();
@@ -1845,48 +1948,46 @@
     }
 
     /**
-     * Checks if the calling app is running in a profile.
+     * Checks if the calling context user is running in a profile.
+     *
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the
+     * caller must be in the same profile group of specified user.
      *
      * @return whether the caller is in a profile.
      * @hide
      */
+    @SystemApi
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+    @UserHandleAware
     public boolean isProfile() {
-        // No need for synchronization.  Once it becomes non-null, it'll be non-null forever.
-        // Worst case we might end up calling the AIDL method multiple times but that's fine.
-        if (mIsProfileCached != null) {
-            return mIsProfileCached;
-        }
-        try {
-            mIsProfileCached = mService.isProfile(UserHandle.myUserId());
-            return mIsProfileCached;
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
+        return isProfile(mUserId);
+    }
+
+    private boolean isProfile(@UserIdInt int userId) {
+        if (userId == UserHandle.myUserId()) {
+            // No need for synchronization.  Once it becomes non-null, it'll be non-null forever.
+            // Worst case we might end up calling the AIDL method multiple times but that's fine.
+            if (mIsProfileCached != null) {
+                return mIsProfileCached;
+            }
+            try {
+                mIsProfileCached = mService.isProfile(userId);
+                return mIsProfileCached;
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        } else {
+            try {
+                return mService.isProfile(userId);
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
         }
     }
 
     /**
-     * Checks if the specified user is a profile.
-     *
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} or
-     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission, otherwise the caller
-     * must be in the same profile group of specified user.
-     *
-     * @return whether the specified user is a profile.
-     * @hide
-     */
-    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
-            android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
-    public boolean isProfile(@UserIdInt int userId) {
-        if (userId == UserHandle.myUserId()) {
-            return isProfile();
-        }
-        try {
-            return mService.isProfile(userId);
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
-    }
-    /**
      * Checks if the calling app is running in a managed profile.
      *
      * @return whether the caller is in a managed profile.
@@ -1915,7 +2016,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isManagedProfile(@UserIdInt int userId) {
         if (userId == UserHandle.myUserId()) {
             return isManagedProfile();
@@ -1933,6 +2035,8 @@
      * @return whether the caller is an ephemeral user.
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isEphemeralUser() {
         return isUserEphemeral(UserHandle.myUserId());
     }
@@ -1941,6 +2045,8 @@
      * Returns whether the specified user is ephemeral.
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean isUserEphemeral(@UserIdInt int userId) {
         final UserInfo user = getUserInfo(userId);
         return user != null && user.isEphemeral();
@@ -1962,12 +2068,15 @@
      *
      * @param user The user to retrieve the running state for.
      */
-    // Note this requires either INTERACT_ACROSS_USERS or MANAGE_USERS.
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserRunning(UserHandle user) {
         return isUserRunning(user.getIdentifier());
     }
 
     /** {@hide} */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserRunning(@UserIdInt int userId) {
         try {
             return mService.isUserRunning(userId);
@@ -1991,7 +2100,8 @@
      *
      * @param user The user to retrieve the running state for.
      */
-    // Note this requires either INTERACT_ACROSS_USERS or MANAGE_USERS.
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserRunningOrStopping(UserHandle user) {
         try {
             // TODO: reconcile stopped vs stopping?
@@ -2038,12 +2148,16 @@
      * @see Intent#ACTION_USER_UNLOCKED
      * @see Context#createDeviceProtectedStorageContext()
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserUnlocked(UserHandle user) {
         return isUserUnlocked(user.getIdentifier());
     }
 
     /** {@hide} */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserUnlocked(@UserIdInt int userId) {
         try {
             return mService.isUserUnlocked(userId);
@@ -2071,15 +2185,15 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(anyOf = {
-            Manifest.permission.MANAGE_USERS,
-            Manifest.permission.INTERACT_ACROSS_USERS
-    })
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserUnlockingOrUnlocked(@NonNull UserHandle user) {
         return isUserUnlockingOrUnlocked(user.getIdentifier());
     }
 
     /** {@hide} */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
     public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
         try {
             return mService.isUserUnlockingOrUnlocked(userId);
@@ -2120,12 +2234,13 @@
 
     /**
      * Returns the UserInfo object describing a specific user.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param userId the user handle of the user whose information is being requested.
      * @return the UserInfo object for a specific user.
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public UserInfo getUserInfo(@UserIdInt int userId) {
         try {
             return mService.getUserInfo(userId);
@@ -2215,6 +2330,7 @@
      * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
      */
     @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
     public boolean hasBaseUserRestriction(@UserRestrictionKey String restrictionKey,
             UserHandle userHandle) {
         try {
@@ -2255,6 +2371,7 @@
      * android.content.ComponentName, String)} instead.
      */
     @Deprecated
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
     public void setUserRestriction(String key, boolean value) {
         setUserRestriction(key, value, Process.myUserHandle());
     }
@@ -2262,7 +2379,6 @@
     /**
      * @hide
      * Sets the value of a specific restriction on a specific user.
-     * Requires the MANAGE_USERS permission.
      * @param key the key of the restriction
      * @param value the value for the restriction
      * @param userHandle the user whose restriction is to be changed.
@@ -2272,6 +2388,7 @@
      * android.content.ComponentName, String)} instead.
      */
     @Deprecated
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
     public void setUserRestriction(String key, boolean value, UserHandle userHandle) {
         try {
             mService.setUserRestriction(key, value, userHandle.getIdentifier());
@@ -2424,21 +2541,32 @@
      * Creates a user with the specified name and options. For non-admin users, default user
      * restrictions will be applied.
      *
-     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS}.
+     * {@link android.Manifest.permission#CREATE_USERS} suffices if flags are in
+     * com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION}.
      *
-     * @param name the user's name
+     * @param name     the user's name
      * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
-     * @param flags UserInfo flags that specify user properties.
-     * @see UserInfo
+     * @param flags    UserInfo flags that specify user properties.
+     * @return the {@link UserInfo} object for the created user,
+     *         or throws {@link UserOperationException} if the user could not be created
+     *         and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
+     *         (otherwise returns {@code null}).
      *
-     * @return the UserInfo object for the created user, or {@code null} if the user could not be
-     * created.
+     * @throws UserOperationException if the user could not be created and the calling app is
+     *         targeting {@link android.os.Build.VERSION_CODES#R} or above.
      * @hide
+     * @see UserInfo
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public @Nullable UserInfo createUser(@Nullable String name, @NonNull String userType,
             @UserInfoFlag int flags) {
         try {
-            return mService.createUser(name, userType, flags);
+            return mService.createUserWithThrow(name, userType, flags);
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2460,21 +2588,30 @@
      *
      * <p>All pre-created users are removed during system upgrade.
      *
-     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS}.
+     * {@link android.Manifest.permission#CREATE_USERS} suffices if flags are in
+     * com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION}.
      *
      * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}.
-     * @return the UserInfo object for the created user, or {@code null} if the user could not be
-     * created.
+     * @return the {@link UserInfo} object for the created user,
+     *         or throws {@link UserOperationException} if the user could not be created
+     *         and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
+     *         (otherwise returns {@code null}).
      *
-     * @throw {@link IllegalArgumentException} if {@code flags} contains
-     * {@link UserInfo#FLAG_MANAGED_PROFILE}.
+     * @throws UserOperationException if the user could not be created and the calling app is
+     *         targeting {@link android.os.Build.VERSION_CODES#R} or above.
      *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
-    public @Nullable UserInfo preCreateUser(@NonNull String userType) {
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
+    public @Nullable UserInfo preCreateUser(@NonNull String userType)
+            throws UserOperationException {
         try {
-            return mService.preCreateUser(userType);
+            return mService.preCreateUserWithThrow(userType);
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2484,16 +2621,28 @@
      * Creates a guest user and configures it.
      * @param context an application context
      * @param name the name to set for the user
+     * @return the {@link UserInfo} object for the created user,
+     *         or throws {@link UserOperationException} if the user could not be created
+     *         and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
+     *         (otherwise returns {@code null}).
+     *
+     * @throws UserOperationException if the user could not be created and the calling app is
+     *         targeting {@link android.os.Build.VERSION_CODES#R} or above.
      * @hide
      */
-    public UserInfo createGuest(Context context, String name) {
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
+    public UserInfo createGuest(Context context, String name) throws UserOperationException {
         UserInfo guest = null;
         try {
-            guest = mService.createUser(name, USER_TYPE_FULL_GUEST, 0);
+            guest = mService.createUserWithThrow(name, USER_TYPE_FULL_GUEST, 0);
             if (guest != null) {
                 Settings.Secure.putStringForUser(context.getContentResolver(),
                         Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
             }
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2515,9 +2664,42 @@
     }
 
     /**
+     * Creates a user with the specified name and options as a profile of the context's user.
+     *
+     * @param name the user's name.
+     * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
+     * @param disallowedPackages packages to not install for this profile.
+     *
+     * @return the {@link android.os.UserHandle} object for the created user,
+     *         or throws {@link UserOperationException} if the user could not be created
+     *         and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
+     *         (otherwise returns {@code null}).
+     *
+     * @throws UserOperationException if the user could not be created and the calling app is
+     *         targeting {@link android.os.Build.VERSION_CODES#R} or above.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
+    @UserHandleAware
+    public @Nullable UserHandle createProfile(@NonNull String name, @NonNull String userType,
+            @Nullable String[] disallowedPackages) throws UserOperationException {
+        try {
+            return mService.createProfileForUserWithThrow(name, userType, 0,
+                    mUserId, disallowedPackages).getUserHandle();
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Creates a user with the specified name and options as a profile of another user.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
-     * The type of profile must be specified using the given flags.
+     * <p>Requires MANAGE_USERS. CREATE_USERS suffices for ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION
      *
      * @param name the user's name
      * @param flags flags that identify the type of user and other properties.
@@ -2530,6 +2712,8 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     @Deprecated
     public UserInfo createProfileForUser(String name, @UserInfoFlag int flags,
             @UserIdInt int userId) {
@@ -2539,7 +2723,6 @@
 
     /**
      * Creates a user with the specified name and options as a profile of another user.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @param name the user's name
      * @param userType the type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
@@ -2550,6 +2733,8 @@
      *         could not be created.
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public UserInfo createProfileForUser(String name, @NonNull String userType,
             @UserInfoFlag int flags, @UserIdInt int userId) {
         return createProfileForUser(name, userType, flags, userId, null);
@@ -2566,14 +2751,26 @@
      * @param userId new user will be a profile of this user.
      * @param disallowedPackages packages that will not be installed in the profile being created.
      *
-     * @return the {@link UserInfo} object for the created user, or null if the user
-     *         could not be created.
+     * @return the {@link UserInfo} object for the created user,
+     *         or throws {@link UserOperationException} if the user could not be created
+     *         and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
+     *         (otherwise returns {@code null}).
+     *
+     * @throws UserOperationException if the user could not be created and the calling app is
+     *         targeting {@link android.os.Build.VERSION_CODES#R} or above.
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public UserInfo createProfileForUser(String name, @NonNull String userType,
-            @UserInfoFlag int flags, @UserIdInt int userId, String[] disallowedPackages) {
+            @UserInfoFlag int flags, @UserIdInt int userId, String[] disallowedPackages)
+            throws UserOperationException {
         try {
-            return mService.createProfileForUser(name, userType, flags, userId, disallowedPackages);
+            return mService.createProfileForUserWithThrow(name, userType, flags, userId,
+                    disallowedPackages);
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2582,17 +2779,21 @@
     /**
      * Similar to {@link #createProfileForUser(String, String, int, int, String[])}
      * except bypassing the checking of {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE}.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @see #createProfileForUser(String, String, int, int, String[])
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public UserInfo createProfileForUserEvenWhenDisallowed(String name,
             @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId,
-            String[] disallowedPackages) {
+            String[] disallowedPackages) throws UserOperationException {
         try {
-            return mService.createProfileForUserEvenWhenDisallowed(name, userType, flags,
+            return mService.createProfileForUserEvenWhenDisallowedWithThrow(name, userType, flags,
                     userId, disallowedPackages);
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2603,19 +2804,30 @@
      * restrictions and adds shared accounts.
      *
      * @param name profile's name
-     * @return UserInfo object for the created user, or null if the user could not be created.
+     * @return the {@link UserInfo} object for the created user,
+     *         or throws {@link UserOperationException} if the user could not be created
+     *         and calling app is targeting {@link android.os.Build.VERSION_CODES#R} or above
+     *         (otherwise returns {@code null}).
+     *
+     * @throws UserOperationException if the user could not be created and the calling app is
+     *         targeting {@link android.os.Build.VERSION_CODES#R} or above.
      * @hide
      */
-    public UserInfo createRestrictedProfile(String name) {
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
+    public UserInfo createRestrictedProfile(String name) throws UserOperationException {
         try {
             UserHandle parentUserHandle = Process.myUserHandle();
-            UserInfo user = mService.createRestrictedProfile(name,
+            UserInfo user = mService.createRestrictedProfileWithThrow(name,
                     parentUserHandle.getIdentifier());
             if (user != null) {
                 AccountManager.get(mContext).addSharedAccountsFromParentUser(parentUserHandle,
                         UserHandle.of(user.id));
             }
             return user;
+        } catch (ServiceSpecificException e) {
+            return returnNullOrThrowUserOperationException(e,
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -2732,6 +2944,7 @@
      * @param accountOptions
      * @see #createUserCreationIntent(String, String, String, PersistableBundle)
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public void setSeedAccountData(int userId, String accountName, String accountType,
             PersistableBundle accountOptions) {
         try {
@@ -2763,6 +2976,7 @@
      * @param userId
      * @return
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean markGuestForDeletion(@UserIdInt int userId) {
         try {
             return mService.markGuestForDeletion(userId);
@@ -2774,8 +2988,6 @@
     /**
      * Sets the user as enabled, if such an user exists.
      *
-     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
-     *
      * <p>Note that the default is true, it's only that managed profiles might not be enabled.
      * Also ephemeral users can be disabled to indicate that their removal is in progress and they
      * shouldn't be re-entered. Therefore ephemeral users should not be re-enabled once disabled.
@@ -2783,6 +2995,7 @@
      * @param userId the id of the profile to enable
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public void setUserEnabled(@UserIdInt int userId) {
         try {
             mService.setUserEnabled(userId);
@@ -2816,6 +3029,7 @@
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public void evictCredentialEncryptionKey(@UserIdInt int userId) {
         try {
             mService.evictCredentialEncryptionKey(userId);
@@ -2829,6 +3043,7 @@
      * <p>This API is not for use by third-party apps. It requires the {@code MANAGE_USERS}
      * permission.</p>
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public int getUserCount() {
         List<UserInfo> users = getUsers();
         return users != null ? users.size() : 1;
@@ -2947,11 +3162,11 @@
 
     /**
      * Returns information for Primary user.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @return the Primary user, null if not found.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public @Nullable UserInfo getPrimaryUser() {
         try {
             return mService.getPrimaryUser();
@@ -2967,6 +3182,7 @@
      * @return true if more users can be added, false if limit has been reached.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean canAddMoreUsers() {
         // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. Why
         //                    not here? The logic is inconsistent. See UMS.canAddMoreManagedProfiles
@@ -2991,6 +3207,7 @@
      * @return true if more managed profiles can be added, false if limit has been reached.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) {
         try {
             return mService.canAddMoreManagedProfiles(userId, allowedToRemoveOne);
@@ -3020,12 +3237,15 @@
      * Note that this returns both enabled and not enabled profiles. See
      * {@link #getEnabledProfiles(int)} if you need only the enabled ones.
      *
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS}.
+     * {@link android.Manifest.permission#CREATE_USERS} suffices if userId is the calling user.
      * @param userId profiles of this user will be returned.
      * @return the list of profiles.
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS}, conditional = true)
     public List<UserInfo> getProfiles(@UserIdInt int userId) {
         try {
             return mService.getProfiles(userId, false /* enabledOnly */);
@@ -3041,7 +3261,6 @@
      * @param otherUser one of the two user handles to check.
      * @return true if the two users are in the same profile group.
      *
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @hide
      */
     @SystemApi
@@ -3051,12 +3270,13 @@
     }
 
     /**
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * Checks if the 2 provided user ids belong to the same profile group.
      * @param userId one of the two user ids to check.
      * @param otherUserId one of the two user ids to check.
      * @return true if the two user ids are in the same profile group.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) {
         try {
             return mService.isSameProfileGroup(userId, otherUserId);
@@ -3069,12 +3289,15 @@
      * Returns list of the profiles of userId including userId itself.
      * Note that this returns only enabled.
      *
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * <p>Requires {@link android.Manifest.permission#MANAGE_USERS}.
+     * {@link android.Manifest.permission#CREATE_USERS} suffices if userId is the calling user.
      * @param userId profiles of this user will be returned.
      * @return the list of profiles.
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS}, conditional = true)
     public List<UserInfo> getEnabledProfiles(@UserIdInt int userId) {
         try {
             return mService.getProfiles(userId, true /* enabledOnly */);
@@ -3099,6 +3322,28 @@
     }
 
     /**
+     * Returns a list of ids for profiles associated with the context user including the user
+     * itself.
+     *
+     * @param enabledOnly whether to return only {@link UserInfo#isEnabled() enabled} profiles
+     * @return A non-empty list of UserHandles associated with the calling user.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS}, conditional = true)
+    @UserHandleAware
+    public @NonNull List<UserHandle> getUserProfiles(boolean enabledOnly) {
+        final int[] userIds = getProfileIds(mUserId, enabledOnly);
+        final List<UserHandle> result = new ArrayList<>(userIds.length);
+        for (int userId : userIds) {
+            result.add(UserHandle.of(userId));
+        }
+        return result;
+    }
+
+    /**
      * Returns a list of ids for profiles associated with the specified user including the user
      * itself.
      *
@@ -3123,6 +3368,8 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS}, conditional = true)
     public int[] getProfileIdsWithDisabled(@UserIdInt int userId) {
         return getProfileIds(userId, false /* enabledOnly */);
     }
@@ -3131,6 +3378,8 @@
      * @see #getProfileIds(int, boolean)
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS}, conditional = true)
     public int[] getEnabledProfileIds(@UserIdInt int userId) {
         return getProfileIds(userId, true /* enabledOnly */);
     }
@@ -3142,6 +3391,7 @@
      *
      * @hide
      */
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
     public int getCredentialOwnerProfile(@UserIdInt int userId) {
         try {
             return mService.getCredentialOwnerProfile(userId);
@@ -3157,6 +3407,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public UserInfo getProfileParent(@UserIdInt int userId) {
         try {
             return mService.getProfileParent(userId);
@@ -3211,11 +3462,32 @@
      *
      * @see #isQuietModeEnabled(UserHandle)
      */
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            Manifest.permission.MODIFY_QUIET_MODE}, conditional = true)
     public boolean requestQuietModeEnabled(boolean enableQuietMode, @NonNull UserHandle userHandle) {
         return requestQuietModeEnabled(enableQuietMode, userHandle, null);
     }
 
     /**
+     * Perform the same operation as {@link #requestQuietModeEnabled(boolean, UserHandle)}, but
+     * with a flag to tweak the behavior of the request.
+     *
+     * @param enableQuietMode whether quiet mode should be enabled or disabled
+     * @param userHandle user handle of the profile
+     * @param flags Can be 0 or {@link #QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED}.
+     * @return {@code false} if user's credential is needed in order to turn off quiet mode,
+     *         {@code true} otherwise
+     * @throws SecurityException if the caller is invalid
+     * @throws IllegalArgumentException if {@code userHandle} is not a managed profile
+     *
+     * @see #isQuietModeEnabled(UserHandle)
+     */
+    public boolean requestQuietModeEnabled(boolean enableQuietMode, @NonNull UserHandle userHandle,
+            @QuietModeFlag int flags) {
+        return requestQuietModeEnabled(enableQuietMode, userHandle, null, flags);
+    }
+
+    /**
      * Similar to {@link #requestQuietModeEnabled(boolean, UserHandle)}, except you can specify
      * a target to start when user is unlocked. If {@code target} is specified, caller must have
      * the {@link android.Manifest.permission#MANAGE_USERS} permission.
@@ -3223,11 +3495,26 @@
      * @see {@link #requestQuietModeEnabled(boolean, UserHandle)}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean requestQuietModeEnabled(
             boolean enableQuietMode, @NonNull UserHandle userHandle, IntentSender target) {
+        return requestQuietModeEnabled(enableQuietMode, userHandle, target, 0);
+    }
+    /**
+     * Similar to {@link #requestQuietModeEnabled(boolean, UserHandle)}, except you can specify
+     * a target to start when user is unlocked. If {@code target} is specified, caller must have
+     * the {@link android.Manifest.permission#MANAGE_USERS} permission.
+     *
+     * @see {@link #requestQuietModeEnabled(boolean, UserHandle)}
+     * @hide
+     */
+    public boolean requestQuietModeEnabled(
+            boolean enableQuietMode, @NonNull UserHandle userHandle, IntentSender target,
+            int flags) {
         try {
             return mService.requestQuietModeEnabled(
-                    mContext.getPackageName(), enableQuietMode, userHandle.getIdentifier(), target);
+                    mContext.getPackageName(), enableQuietMode, userHandle.getIdentifier(), target,
+                    flags);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -3270,15 +3557,16 @@
     }
 
     /**
-     * Returns whether the calling app's user has a badge (generally to put on profiles' icons).
+     * Returns whether the user associated with the context has a badge (generally to put on
+     * profiles' icons).
      *
      * @return true if the user's icons should display a badge; false otherwise.
-     *
      * @see #getBadgedIconForUser more information about badging in general
      * @hide
      */
+    @UserHandleAware
     public boolean hasBadge() {
-        return hasBadge(UserHandle.myUserId());
+        return hasBadge(mUserId);
     }
 
     /**
@@ -3436,11 +3724,12 @@
 
     /**
      * Removes a user and all associated data.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param userId the integer handle of the user.
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean removeUser(@UserIdInt int userId) {
         try {
             return mService.removeUser(userId);
@@ -3458,7 +3747,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean removeUser(@NonNull UserHandle user) {
         if (user == null) {
             throw new IllegalArgumentException("user cannot be null");
@@ -3475,6 +3765,8 @@
      * @see {@link #removeUser(int)}
      * @hide
      */
+    @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+            Manifest.permission.CREATE_USERS})
     public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
         try {
             return mService.removeUserEvenWhenDisallowed(userId);
@@ -3485,12 +3777,12 @@
 
     /**
      * Updates the user's name.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
      * @param userId the user's integer id
      * @param name the new name for the user
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public void setUserName(@UserIdInt int userId, String name) {
         try {
             mService.setUserName(userId, name);
@@ -3500,16 +3792,16 @@
     }
 
     /**
-     * Updates the calling user's name.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * Updates the context user's name.
      *
      * @param name the new name for the user
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    @UserHandleAware
     public void setUserName(@Nullable String name) {
-        setUserName(getUserHandle(), name);
+        setUserName(mUserId, name);
     }
 
     /**
@@ -3518,35 +3810,41 @@
      * @param icon the bitmap to set as the photo.
      * @hide
      */
-    public void setUserIcon(@UserIdInt int userId, Bitmap icon) {
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    public void setUserIcon(@UserIdInt int userId, @NonNull Bitmap icon)
+            throws UserOperationException {
         try {
             mService.setUserIcon(userId, icon);
+        } catch (ServiceSpecificException e) {
+            throw UserOperationException.from(e);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Sets the calling user's photo.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * Sets the context user's photo.
      *
      * @param icon the bitmap to set as the photo.
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
-    public void setUserIcon(@NonNull Bitmap icon) {
-        setUserIcon(getUserHandle(), icon);
+    @UserHandleAware
+    public void setUserIcon(@NonNull Bitmap icon) throws UserOperationException {
+        setUserIcon(mUserId, icon);
     }
 
     /**
-     * Returns a file descriptor for the user's photo. PNG data can be read from this file.
+     * Returns a bitmap of the user's photo
      * @param userId the user whose photo we want to read.
      * @return a {@link Bitmap} of the user's photo, or null if there's no photo.
      * @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default.
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED})
     public Bitmap getUserIcon(@UserIdInt int userId) {
         try {
             ParcelFileDescriptor fd = mService.getUserIcon(userId);
@@ -3567,9 +3865,7 @@
     }
 
     /**
-     * Returns a Bitmap for the calling user's photo.
-     * Requires {@link android.Manifest.permission#MANAGE_USERS}
-     * or {@link android.Manifest.permission#GET_ACCOUNTS_PRIVILEGED} permissions.
+     * Returns a Bitmap for the context user's photo.
      *
      * @return a {@link Bitmap} of the user's photo, or null if there's no photo.
      * @see com.android.internal.util.UserIcons#getDefaultUserIcon for a default.
@@ -3578,8 +3874,9 @@
     @SystemApi
     @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
             android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED})
+    @UserHandleAware
     public @Nullable Bitmap getUserIcon() {
-        return getUserIcon(getUserHandle());
+        return getUserIcon(mUserId);
     }
 
     /**
@@ -3756,6 +4053,7 @@
      * @hide
      * Set restrictions that should apply to any future guest user that's created.
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public void setDefaultGuestRestrictions(Bundle restrictions) {
         try {
             mService.setDefaultGuestRestrictions(restrictions);
@@ -3768,6 +4066,7 @@
      * @hide
      * Gets the default guest restrictions.
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public Bundle getDefaultGuestRestrictions() {
         try {
             return mService.getDefaultGuestRestrictions();
@@ -3798,6 +4097,7 @@
      * @param accountType The account type of the account to check for
      * @return whether the seed account was found
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     public boolean someUserHasSeedAccount(String accountName, String accountType) {
         try {
             return mService.someUserHasSeedAccount(accountName, accountType);
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 92fecad..bbc936d 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -193,4 +193,5 @@
     void startCheckpoint(int numTries) = 85;
     boolean needsCheckpoint() = 86;
     void abortChanges(in String message, boolean retry) = 87;
+    void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88;
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0e3dd3a..eee8fb1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7488,6 +7488,21 @@
         public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior";
 
         /**
+         * Whether the user allows minimal post processing or not.
+         *
+         * <p>Values:
+         * 0 - Not allowed. Any preferences set through the Window.setPreferMinimalPostProcessing
+         *     API will be ignored.
+         * 1 - Allowed. Any preferences set through the Window.setPreferMinimalPostProcessing API
+         *     will be respected and the appropriate signals will be sent to display.
+         *     (Default behaviour)
+         *
+         * @hide
+         */
+        public static final String MINIMAL_POST_PROCESSING_ALLOWED =
+                "minimal_post_processing_allowed";
+
+        /**
          * INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen".
          * @hide
          */
@@ -7598,6 +7613,12 @@
         public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
 
         /**
+         * Whether the device should suppress the current doze configuration and disable dozing.
+         * @hide
+         */
+        public static final String SUPPRESS_DOZE = "suppress_doze";
+
+        /**
          * Gesture that skips media.
          * @hide
          */
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index f369064..4537281 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5374,5 +5374,11 @@
 
         /** Whether uicc applications is set to be enabled or disabled. By default it's enabled. */
         public static final String UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled";
+
+        /**
+         * TelephonyProvider column name for allowed network types. Indicate which network types
+         * are allowed. Default is -1.
+         */
+        public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types";
     }
 }
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index 00060ab..a5c5c61 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -98,6 +98,8 @@
 
     private static final String TAG = "OMAPI.SEService";
 
+    private static final String UICC_TERMINAL = "SIM";
+
     private final Object mLock = new Object();
 
     /** The client context (e.g. activity). */
@@ -190,32 +192,33 @@
      * is of length 0.
      */
     public @NonNull Reader[] getReaders() {
-        if (mSecureElementService == null) {
-            throw new IllegalStateException("service not connected to system");
-        }
-        String[] readerNames;
-        try {
-            readerNames = mSecureElementService.getReaders();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
+        loadReaders();
 
-        Reader[] readers = new Reader[readerNames.length];
-        int i = 0;
-        for (String readerName : readerNames) {
-            if (mReaders.get(readerName) == null) {
-                try {
-                    mReaders.put(readerName, new Reader(this, readerName,
-                            getReader(readerName)));
-                    readers[i++] = mReaders.get(readerName);
-                } catch (Exception e) {
-                    Log.e(TAG, "Error adding Reader: " + readerName, e);
-                }
-            } else {
-                readers[i++] = mReaders.get(readerName);
-            }
-        }
-        return readers;
+        return mReaders.values().toArray(new Reader[0]);
+    }
+
+    /**
+      * Obtain a UICC Reader instance with specific slot number from the SecureElementService
+      *
+      * @param slotNumber The index of the uicc slot. The index starts from 1.
+      * @throws IllegalArgumentException if the reader object corresponding to the uiccSlotNumber
+      *         is not exist.
+      * @return A Reader object for this uicc slot.
+      */
+     public @NonNull Reader getUiccReader(int slotNumber) {
+         if (slotNumber < 1) {
+             throw new IllegalArgumentException("slotNumber should be larger than 0");
+         }
+         loadReaders();
+
+         String readerName = UICC_TERMINAL + slotNumber;
+         Reader reader = mReaders.get(readerName);
+
+         if (reader == null) {
+            throw new IllegalArgumentException("Reader:" + readerName + " doesn't exist");
+         }
+
+         return reader;
     }
 
     /**
@@ -270,4 +273,30 @@
             throw new IllegalStateException(e.getMessage());
         }
     }
+
+    /**
+     * Load available Secure Element Readers
+     */
+    private void loadReaders() {
+        if (mSecureElementService == null) {
+            throw new IllegalStateException("service not connected to system");
+        }
+        String[] readerNames;
+        try {
+            readerNames = mSecureElementService.getReaders();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+
+        for (String readerName : readerNames) {
+            if (mReaders.get(readerName) == null) {
+                try {
+                    mReaders.put(readerName, new Reader(this, readerName,
+                            getReader(readerName)));
+                } catch (Exception e) {
+                    Log.e(TAG, "Error adding Reader: " + readerName, e);
+                }
+            }
+        }
+    }
 }
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 939ae87..dc0f562 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -559,8 +559,8 @@
         }
 
         /**
-         * Sets targets with the resources IDs of the child view of
-         * {@link RemoteViews Presentation Template} which will cancel the session when clicked.
+         * Sets target resource IDs of the child view in {@link RemoteViews Presentation Template}
+         * which will cancel the session when clicked.
          * Those targets will be respectively applied to a child of the header, footer and
          * each {@link Dataset}.
          *
@@ -571,7 +571,7 @@
          * @throws IllegalStateException if {@link #build()} was already called.
          */
         @NonNull
-        public Builder setCancelTargetIds(@Nullable int[] ids) {
+        public Builder setPresentationCancelIds(@Nullable int[] ids) {
             throwIfDestroyed();
             mCancelIds = ids;
             return this;
@@ -769,7 +769,7 @@
             }
             builder.setFlags(parcel.readInt());
             final int[] cancelIds = parcel.createIntArray();
-            builder.setCancelTargetIds(cancelIds);
+            builder.setPresentationCancelIds(cancelIds);
 
             final FillResponse response = builder.build();
             response.setRequestId(parcel.readInt());
diff --git a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java b/core/java/android/service/euicc/IEuiccServiceDumpResultCallback.aidl
similarity index 74%
copy from apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
copy to core/java/android/service/euicc/IEuiccServiceDumpResultCallback.aidl
index a534e22..ea55ebb 100644
--- a/apex/permission/service/java/com/android/server/permission/RuntimePermissionPersistence.java
+++ b/core/java/android/service/euicc/IEuiccServiceDumpResultCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.server.permission;
+package android.service.euicc;
 
-/**
- * Persistence for runtime permissions.
- */
-public class RuntimePermissionPersistence {}
+/** @hide */
+oneway interface IEuiccServiceDumpResultCallback {
+    void onComplete(in String logs);
+}
\ No newline at end of file
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 389040c..4f400a8 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -16,6 +16,9 @@
 
 package android.service.notification;
 
+import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
+import static android.util.FeatureFlagUtils.*;
+
 import android.annotation.NonNull;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -29,6 +32,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -436,6 +441,19 @@
         return logMaker;
     }
 
+    /**
+     * @hide
+     */
+    public String getShortcutId(Context context) {
+        String conversationId = getNotification().getShortcutId();
+        if (isEnabled(context,  NOTIF_CONVO_BYPASS_SHORTCUT_REQ)
+                && getNotification().getNotificationStyle() == Notification.MessagingStyle.class
+                && TextUtils.isEmpty(conversationId)) {
+            conversationId = getId() + getTag() + PLACEHOLDER_CONVERSATION_ID;
+        }
+        return conversationId;
+    }
+
     private String getGroupLogTag() {
         return shortenTag(getGroup());
     }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 9a76a1b..e3fd8d2 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -31,6 +31,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
@@ -188,6 +189,7 @@
         DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT;
         final InsetsState mInsetsState = new InsetsState();
         final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
+        private final Point mSurfaceSize = new Point();
 
         final WindowManager.LayoutParams mLayout
                 = new WindowManager.LayoutParams();
@@ -838,12 +840,13 @@
                     } else {
                         mLayout.surfaceInsets.set(0, 0, 0, 0);
                     }
+
                     final int relayoutResult = mSession.relayout(
                         mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                             View.VISIBLE, 0, -1, mWinFrame, mContentInsets,
                             mVisibleInsets, mStableInsets, mBackdropFrame,
                             mDisplayCutout, mMergedConfiguration, mSurfaceControl,
-                            mInsetsState);
+                            mInsetsState, mSurfaceSize);
                     if (mSurfaceControl.isValid()) {
                         mSurfaceHolder.mSurface.copyFrom(mSurfaceControl);
                         mSurfaceControl.release();
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 615dab0..d433591 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -86,7 +86,7 @@
      * @hide
      */
     public static final DisplayCutout NO_CUTOUT = new DisplayCutout(
-            ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT,
+            ZERO_RECT, Insets.NONE, ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT,
             false /* copyArguments */);
 
 
@@ -103,8 +103,12 @@
     private static float sCachedDensity;
     @GuardedBy("CACHE_LOCK")
     private static Pair<Path, DisplayCutout> sCachedCutout = NULL_PAIR;
+    @GuardedBy("CACHE_LOCK")
+    private static Insets sCachedWaterfallInsets;
 
     private final Rect mSafeInsets;
+    @NonNull
+    private final Insets mWaterfallInsets;
 
 
     /**
@@ -251,7 +255,32 @@
     // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
     public DisplayCutout(@NonNull Insets safeInsets, @Nullable Rect boundLeft,
             @Nullable Rect boundTop, @Nullable Rect boundRight, @Nullable Rect boundBottom) {
-        this(safeInsets.toRect(), boundLeft, boundTop, boundRight, boundBottom, true);
+        this(safeInsets.toRect(), Insets.NONE, boundLeft, boundTop, boundRight, boundBottom, true);
+    }
+
+    /**
+     * Creates a DisplayCutout instance.
+     *
+     * <p>Note that this is only useful for tests. For production code, developers should always
+     * use a {@link DisplayCutout} obtained from the system.</p>
+     *
+     * @param safeInsets the insets from each edge which avoid the display cutout as returned by
+     *                   {@link #getSafeInsetTop()} etc.
+     * @param boundLeft the left bounding rect of the display cutout in pixels. If null is passed,
+     *                  it's treated as an empty rectangle (0,0)-(0,0).
+     * @param boundTop the top bounding rect of the display cutout in pixels.  If null is passed,
+     *                  it's treated as an empty rectangle (0,0)-(0,0).
+     * @param boundRight the right bounding rect of the display cutout in pixels.  If null is
+     *                  passed, it's treated as an empty rectangle (0,0)-(0,0).
+     * @param boundBottom the bottom bounding rect of the display cutout in pixels.  If null is
+     *                   passed, it's treated as an empty rectangle (0,0)-(0,0).
+     * @param waterfallInsets the insets for the curved areas in waterfall display.
+     */
+    public DisplayCutout(@NonNull Insets safeInsets, @Nullable Rect boundLeft,
+            @Nullable Rect boundTop, @Nullable Rect boundRight, @Nullable Rect boundBottom,
+            @NonNull Insets waterfallInsets) {
+        this(safeInsets.toRect(), waterfallInsets, boundLeft, boundTop, boundRight, boundBottom,
+                true);
     }
 
     /**
@@ -269,7 +298,7 @@
     // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
     @Deprecated
     public DisplayCutout(@Nullable Rect safeInsets, @Nullable List<Rect> boundingRects) {
-        this(safeInsets, extractBoundsFromList(safeInsets, boundingRects),
+        this(safeInsets, Insets.NONE, extractBoundsFromList(safeInsets, boundingRects),
                 true /* copyArguments */);
     }
 
@@ -281,19 +310,23 @@
      * @param copyArguments if true, create a copy of the arguments. If false, the passed arguments
      *                      are not copied and MUST remain unchanged forever.
      */
-    private DisplayCutout(Rect safeInsets, Rect boundLeft, Rect boundTop, Rect boundRight,
-                         Rect boundBottom, boolean copyArguments) {
+    private DisplayCutout(Rect safeInsets, Insets waterfallInsets, Rect boundLeft,
+                        Rect boundTop, Rect boundRight, Rect boundBottom, boolean copyArguments) {
         mSafeInsets = getCopyOrRef(safeInsets, copyArguments);
+        mWaterfallInsets = waterfallInsets == null ? Insets.NONE : waterfallInsets;
         mBounds = new Bounds(boundLeft, boundTop, boundRight, boundBottom, copyArguments);
     }
 
-    private DisplayCutout(Rect safeInsets, Rect[] bounds, boolean copyArguments) {
+    private DisplayCutout(Rect safeInsets, Insets waterfallInsets, Rect[] bounds,
+                        boolean copyArguments) {
         mSafeInsets = getCopyOrRef(safeInsets, copyArguments);
+        mWaterfallInsets = waterfallInsets == null ? Insets.NONE : waterfallInsets;
         mBounds = new Bounds(bounds, copyArguments);
     }
 
-    private DisplayCutout(Rect safeInsets, Bounds bounds) {
+    private DisplayCutout(Rect safeInsets, Insets waterfallInsets, Bounds bounds) {
         mSafeInsets = safeInsets;
+        mWaterfallInsets = waterfallInsets == null ? Insets.NONE : waterfallInsets;
         mBounds = bounds;
 
     }
@@ -309,6 +342,14 @@
     }
 
     /**
+     * Return the waterfall insets.
+     */
+    public @NonNull Insets getWaterfallInsets() {
+        return mWaterfallInsets;
+    }
+
+
+    /**
      * Find the position of the bounding rect, and create an array of Rect whose index represents
      * the position (= BoundsPosition).
      *
@@ -476,7 +517,8 @@
 
     @Override
     public int hashCode() {
-        return mSafeInsets.hashCode() * 48271 + mBounds.hashCode();
+        return (mSafeInsets.hashCode() * 48271 + mBounds.hashCode()) * 48271
+                + mWaterfallInsets.hashCode();
     }
 
     @Override
@@ -486,7 +528,8 @@
         }
         if (o instanceof DisplayCutout) {
             DisplayCutout c = (DisplayCutout) o;
-            return mSafeInsets.equals(c.mSafeInsets) && mBounds.equals(c.mBounds);
+            return mSafeInsets.equals(c.mSafeInsets) && mBounds.equals(c.mBounds)
+                    && mWaterfallInsets.equals(c.mWaterfallInsets);
         }
         return false;
     }
@@ -494,6 +537,7 @@
     @Override
     public String toString() {
         return "DisplayCutout{insets=" + mSafeInsets
+                + " waterfall=" + mWaterfallInsets
                 + " boundingRect={" + mBounds + "}"
                 + "}";
     }
@@ -508,6 +552,7 @@
         mBounds.getRect(BOUNDS_POSITION_TOP).dumpDebug(proto, BOUND_TOP);
         mBounds.getRect(BOUNDS_POSITION_RIGHT).dumpDebug(proto, BOUND_RIGHT);
         mBounds.getRect(BOUNDS_POSITION_BOTTOM).dumpDebug(proto, BOUND_BOTTOM);
+        mWaterfallInsets.toRect().dumpDebug(proto, INSETS);
         proto.end(token);
     }
 
@@ -553,7 +598,7 @@
             }
         }
 
-        return new DisplayCutout(safeInsets, bounds, false /* copyArguments */);
+        return new DisplayCutout(safeInsets, mWaterfallInsets, bounds, false /* copyArguments */);
     }
 
     /**
@@ -565,7 +610,7 @@
      * @hide
      */
     public DisplayCutout replaceSafeInsets(Rect safeInsets) {
-        return new DisplayCutout(new Rect(safeInsets), mBounds);
+        return new DisplayCutout(new Rect(safeInsets), mWaterfallInsets, mBounds);
     }
 
     private static int atLeastZero(int value) {
@@ -585,7 +630,16 @@
         for (int i = 0; i < BOUNDS_POSITION_LENGTH; ++i) {
             bounds[i] = (pos == i) ? new Rect(left, top, right, bottom) : new Rect();
         }
-        return new DisplayCutout(ZERO_RECT, bounds, false /* copyArguments */);
+        return new DisplayCutout(ZERO_RECT, Insets.NONE, bounds, false /* copyArguments */);
+    }
+
+    /**
+     * Creates an instance from a bounding and waterfall insets.
+     *
+     * @hide
+     */
+    public static DisplayCutout fromBoundsAndWaterfall(Rect[] bounds, Insets waterfallInsets) {
+        return new DisplayCutout(ZERO_RECT, waterfallInsets, bounds, false /* copyArguments */);
     }
 
     /**
@@ -594,7 +648,7 @@
      * @hide
      */
     public static DisplayCutout fromBounds(Rect[] bounds) {
-        return new DisplayCutout(ZERO_RECT, bounds, false /* copyArguments */);
+        return new DisplayCutout(ZERO_RECT, Insets.NONE, bounds, false /* copyArguments */);
     }
 
     /**
@@ -606,7 +660,8 @@
      */
     public static DisplayCutout fromResourcesRectApproximation(Resources res, int displayWidth, int displayHeight) {
         return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutoutRectApproximation),
-                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT);
+                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
+                loadWaterfallInset(res));
     }
 
     /**
@@ -617,7 +672,8 @@
     public static Path pathFromResources(Resources res, int displayWidth, int displayHeight) {
         return pathAndDisplayCutoutFromSpec(
                 res.getString(R.string.config_mainBuiltInDisplayCutout),
-                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT).first;
+                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
+                loadWaterfallInset(res)).first;
     }
 
     /**
@@ -627,91 +683,109 @@
      */
     @VisibleForTesting(visibility = PRIVATE)
     public static DisplayCutout fromSpec(String spec, int displayWidth, int displayHeight,
-            float density) {
-        return pathAndDisplayCutoutFromSpec(spec, displayWidth, displayHeight, density).second;
+            float density, Insets waterfallInsets) {
+        return pathAndDisplayCutoutFromSpec(
+                spec, displayWidth, displayHeight, density, waterfallInsets).second;
     }
 
     private static Pair<Path, DisplayCutout> pathAndDisplayCutoutFromSpec(String spec,
-            int displayWidth, int displayHeight, float density) {
-        if (TextUtils.isEmpty(spec)) {
+            int displayWidth, int displayHeight, float density, Insets waterfallInsets) {
+        if (TextUtils.isEmpty(spec) && waterfallInsets.equals(Insets.NONE)) {
             return NULL_PAIR;
         }
+
         synchronized (CACHE_LOCK) {
             if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
                     && sCachedDisplayHeight == displayHeight
-                    && sCachedDensity == density) {
+                    && sCachedDensity == density
+                    && waterfallInsets.equals(sCachedWaterfallInsets)) {
                 return sCachedCutout;
             }
         }
-        spec = spec.trim();
-        final float offsetX;
-        if (spec.endsWith(RIGHT_MARKER)) {
-            offsetX = displayWidth;
-            spec = spec.substring(0, spec.length() - RIGHT_MARKER.length()).trim();
-        } else if (spec.endsWith(LEFT_MARKER)) {
-            offsetX = 0;
-            spec = spec.substring(0, spec.length() - LEFT_MARKER.length()).trim();
-        } else {
-            offsetX = displayWidth / 2f;
-        }
-        final boolean inDp = spec.endsWith(DP_MARKER);
-        if (inDp) {
-            spec = spec.substring(0, spec.length() - DP_MARKER.length());
-        }
 
-        String bottomSpec = null;
-        if (spec.contains(BOTTOM_MARKER)) {
-            String[] splits = spec.split(BOTTOM_MARKER, 2);
-            spec = splits[0].trim();
-            bottomSpec = splits[1].trim();
-        }
-
-        final Path p;
-        final Region r = Region.obtain();
-        try {
-            p = PathParser.createPathFromPathData(spec);
-        } catch (Throwable e) {
-            Log.wtf(TAG, "Could not inflate cutout: ", e);
-            return NULL_PAIR;
-        }
-
-        final Matrix m = new Matrix();
-        if (inDp) {
-            m.postScale(density, density);
-        }
-        m.postTranslate(offsetX, 0);
-        p.transform(m);
-
-        Rect boundTop = new Rect();
-        toRectAndAddToRegion(p, r, boundTop);
-        final int topInset = boundTop.bottom;
-
+        Path p = null;
+        Rect boundTop = null;
         Rect boundBottom = null;
-        final int bottomInset;
-        if (bottomSpec != null) {
-            final Path bottomPath;
-            try {
-                bottomPath = PathParser.createPathFromPathData(bottomSpec);
-            } catch (Throwable e) {
-                Log.wtf(TAG, "Could not inflate bottom cutout: ", e);
-                return NULL_PAIR;
+        Rect safeInset = new Rect();
+        String bottomSpec = null;
+        if (!TextUtils.isEmpty(spec)) {
+            spec = spec.trim();
+            final float offsetX;
+            if (spec.endsWith(RIGHT_MARKER)) {
+                offsetX = displayWidth;
+                spec = spec.substring(0, spec.length() - RIGHT_MARKER.length()).trim();
+            } else if (spec.endsWith(LEFT_MARKER)) {
+                offsetX = 0;
+                spec = spec.substring(0, spec.length() - LEFT_MARKER.length()).trim();
+            } else {
+                offsetX = displayWidth / 2f;
             }
-            // Keep top transform
-            m.postTranslate(0, displayHeight);
-            bottomPath.transform(m);
-            p.addPath(bottomPath);
-            boundBottom = new Rect();
-            toRectAndAddToRegion(bottomPath, r, boundBottom);
-            bottomInset = displayHeight - boundBottom.top;
-        } else {
-            bottomInset = 0;
+            final boolean inDp = spec.endsWith(DP_MARKER);
+            if (inDp) {
+                spec = spec.substring(0, spec.length() - DP_MARKER.length());
+            }
+
+            if (spec.contains(BOTTOM_MARKER)) {
+                String[] splits = spec.split(BOTTOM_MARKER, 2);
+                spec = splits[0].trim();
+                bottomSpec = splits[1].trim();
+            }
+
+            final Matrix m = new Matrix();
+            final Region r = Region.obtain();
+            if (!spec.isEmpty()) {
+                try {
+                    p = PathParser.createPathFromPathData(spec);
+                } catch (Throwable e) {
+                    Log.wtf(TAG, "Could not inflate cutout: ", e);
+                }
+
+                if (p != null) {
+                    if (inDp) {
+                        m.postScale(density, density);
+                    }
+                    m.postTranslate(offsetX, 0);
+                    p.transform(m);
+
+                    boundTop = new Rect();
+                    toRectAndAddToRegion(p, r, boundTop);
+                    safeInset.top = boundTop.bottom;
+                }
+            }
+
+            if (bottomSpec != null) {
+                int bottomInset = 0;
+                Path bottomPath = null;
+                try {
+                    bottomPath = PathParser.createPathFromPathData(bottomSpec);
+                } catch (Throwable e) {
+                    Log.wtf(TAG, "Could not inflate bottom cutout: ", e);
+                }
+
+                if (bottomPath != null) {
+                    // Keep top transform
+                    m.postTranslate(0, displayHeight);
+                    bottomPath.transform(m);
+                    p.addPath(bottomPath);
+                    boundBottom = new Rect();
+                    toRectAndAddToRegion(bottomPath, r, boundBottom);
+                    bottomInset = displayHeight - boundBottom.top;
+                }
+                safeInset.bottom = bottomInset;
+            }
         }
 
-        Rect safeInset = new Rect(0, topInset, 0, bottomInset);
-        final DisplayCutout cutout = new DisplayCutout(
-                safeInset, null /* boundLeft */, boundTop, null /* boundRight */, boundBottom,
-                false /* copyArguments */);
+        if (!waterfallInsets.equals(Insets.NONE)) {
+            safeInset.set(
+                    Math.max(waterfallInsets.left, safeInset.left),
+                    Math.max(waterfallInsets.top, safeInset.top),
+                    Math.max(waterfallInsets.right, safeInset.right),
+                    Math.max(waterfallInsets.bottom, safeInset.bottom));
+        }
 
+        final DisplayCutout cutout = new DisplayCutout(
+                safeInset, waterfallInsets, null /* boundLeft */, boundTop,
+                null /* boundRight */, boundBottom, false /* copyArguments */);
         final Pair<Path, DisplayCutout> result = new Pair<>(p, cutout);
         synchronized (CACHE_LOCK) {
             sCachedSpec = spec;
@@ -719,6 +793,7 @@
             sCachedDisplayHeight = displayHeight;
             sCachedDensity = density;
             sCachedCutout = result;
+            sCachedWaterfallInsets = waterfallInsets;
         }
         return result;
     }
@@ -730,6 +805,15 @@
         inoutRegion.op(inoutRect, Op.UNION);
     }
 
+
+    private static Insets loadWaterfallInset(Resources res) {
+        return Insets.of(
+                res.getDimensionPixelSize(R.dimen.waterfall_display_left_edge_size),
+                res.getDimensionPixelSize(R.dimen.waterfall_display_top_edge_size),
+                res.getDimensionPixelSize(R.dimen.waterfall_display_right_edge_size),
+                res.getDimensionPixelSize(R.dimen.waterfall_display_bottom_edge_size));
+    }
+
     /**
      * Helper class for passing {@link DisplayCutout} through binder.
      *
@@ -773,6 +857,7 @@
                 out.writeInt(1);
                 out.writeTypedObject(cutout.mSafeInsets, flags);
                 out.writeTypedArray(cutout.mBounds.getRects(), flags);
+                out.writeTypedObject(cutout.mWaterfallInsets, flags);
             }
         }
 
@@ -815,8 +900,10 @@
             Rect safeInsets = in.readTypedObject(Rect.CREATOR);
             Rect[] bounds = new Rect[BOUNDS_POSITION_LENGTH];
             in.readTypedArray(bounds, Rect.CREATOR);
+            Insets waterfallInsets = in.readTypedObject(Insets.CREATOR);
 
-            return new DisplayCutout(safeInsets, bounds, false /* copyArguments */);
+            return new DisplayCutout(
+                    safeInsets, waterfallInsets, bounds, false /* copyArguments */);
         }
 
         public DisplayCutout get() {
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 7d455c9..b9868a7 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -624,6 +624,8 @@
         sb.append(Arrays.toString(supportedColorModes));
         sb.append(", hdrCapabilities ");
         sb.append(hdrCapabilities);
+        sb.append(", minimalPostProcessingSupported ");
+        sb.append(minimalPostProcessingSupported);
         sb.append(", rotation ");
         sb.append(rotation);
         sb.append(", density ");
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 8f25d89..e3446e1 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -18,6 +18,7 @@
 package android.view;
 
 import android.content.ClipData;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Bundle;
@@ -90,6 +91,7 @@
      * since it was last displayed.
      * @param outSurface Object in which is placed the new display surface.
      * @param insetsState The current insets state in the system.
+     * @param outSurfaceSize The width and height of the surface control
      *
      * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS},
      * {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
@@ -101,7 +103,7 @@
             out Rect outBackdropFrame,
             out DisplayCutout.ParcelableWrapper displayCutout,
             out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
-            out InsetsState insetsState);
+            out InsetsState insetsState, out Point outSurfaceSize);
 
     /*
      * Notify the window manager that an application is relaunching and
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 69d0105..f5afd10 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -239,7 +239,8 @@
         return state.calculateInsets(frame, false /* isScreenRound */,
                 false /* alwaysConsumeSystemBars */, null /* displayCutout */,
                 null /* legacyContentInsets */, null /* legacyStableInsets */,
-                LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/, typeSideMap)
+                LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/,
+                0 /* legacySystemUiFlags */, typeSideMap)
                .getInsets(mTypes);
     }
 
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index e2739c4..411e910 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -19,6 +19,8 @@
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.toPublicType;
 import static android.view.WindowInsets.Type.all;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -28,7 +30,6 @@
 import android.annotation.NonNull;
 import android.graphics.Insets;
 import android.graphics.Rect;
-import android.net.InvalidPacketException.ErrorCode;
 import android.os.RemoteException;
 import android.util.ArraySet;
 import android.util.Log;
@@ -148,13 +149,18 @@
         }
     }
 
-    private class DefaultAnimationControlListener implements WindowInsetsAnimationControlListener {
+    /**
+     * The default implementation of listener, to be used by InsetsController and InsetsPolicy to
+     * animate insets.
+     */
+    public static class InternalAnimationControlListener
+            implements WindowInsetsAnimationControlListener {
 
         private WindowInsetsAnimationController mController;
         private ObjectAnimator mAnimator;
-        private boolean mShow;
+        protected boolean mShow;
 
-        DefaultAnimationControlListener(boolean show) {
+        InternalAnimationControlListener(boolean show) {
             mShow = show;
         }
 
@@ -178,9 +184,9 @@
                     onAnimationFinish();
                 }
             });
-            mStartingAnimation = true;
+            setStartingAnimation(true);
             mAnimator.start();
-            mStartingAnimation = false;
+            setStartingAnimation(false);
         }
 
         @Override
@@ -191,16 +197,19 @@
             }
         }
 
-        private void onAnimationFinish() {
+        protected void setStartingAnimation(boolean startingAnimation) {
+        }
+
+        protected void onAnimationFinish() {
             mController.finish(mShow);
         }
 
-        private float getRawProgress() {
+        protected float getRawProgress() {
             float fraction = (float) mAnimator.getCurrentPlayTime() / mAnimator.getDuration();
             return mShow ? fraction : 1 - fraction;
         }
 
-        private long getDurationMs() {
+        protected long getDurationMs() {
             if (mAnimator != null) {
                 return mAnimator.getDuration();
             }
@@ -222,6 +231,17 @@
         final @AnimationType int type;
     }
 
+    private class DefaultAnimationControlListener extends InternalAnimationControlListener {
+        DefaultAnimationControlListener(boolean show) {
+            super(show);
+        }
+
+        @Override
+        protected void setStartingAnimation(boolean startingAnimation) {
+            mStartingAnimation = startingAnimation;
+        }
+    }
+
     private final String TAG = "InsetsControllerImpl";
 
     private final InsetsState mState = new InsetsState();
@@ -246,6 +266,7 @@
     private int mPendingTypesToShow;
 
     private int mLastLegacySoftInputMode;
+    private int mLastLegacySystemUiFlags;
     private boolean mStartingAnimation;
 
     private SyncRtSurfaceTransactionApplier mApplier;
@@ -274,7 +295,7 @@
             WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(),
                     mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.getDisplayCutout(),
                     mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode,
-                    null /* typeSideMap */);
+                    mLastLegacySystemUiFlags, null /* typeSideMap */);
             mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets);
 
             for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) {
@@ -317,12 +338,13 @@
     @VisibleForTesting
     public WindowInsets calculateInsets(boolean isScreenRound,
             boolean alwaysConsumeSystemBars, DisplayCutout cutout, Rect legacyContentInsets,
-            Rect legacyStableInsets, int legacySoftInputMode) {
+            Rect legacyStableInsets, int legacySoftInputMode, int legacySystemUiFlags) {
         mLastLegacyContentInsets.set(legacyContentInsets);
         mLastLegacyStableInsets.set(legacyStableInsets);
         mLastLegacySoftInputMode = legacySoftInputMode;
+        mLastLegacySystemUiFlags = legacySystemUiFlags;
         mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeSystemBars, cutout,
-                legacyContentInsets, legacyStableInsets, legacySoftInputMode,
+                legacyContentInsets, legacyStableInsets, legacySoftInputMode, legacySystemUiFlags,
                 null /* typeSideMap */);
         return mLastInsets;
     }
@@ -623,6 +645,14 @@
     }
 
     /**
+     * @see ViewRootImpl#updateCompatSysUiVisibility(int, boolean, boolean)
+     */
+    public void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible,
+            boolean hasControl) {
+        mViewRoot.updateCompatSysUiVisibility(type, visible, hasControl);
+    }
+
+    /**
      * Called when current window gains focus.
      */
     public void onWindowFocusGained() {
@@ -779,20 +809,41 @@
     }
 
     @Override
-    public void setSystemBarsAppearance(@Appearance int appearance) {
-        if (mViewRoot.mWindowAttributes.insetsFlags.appearance != appearance) {
-            mViewRoot.mWindowAttributes.insetsFlags.appearance = appearance;
+    public void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask) {
+        mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED;
+        final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags;
+        if (insetsFlags.appearance != appearance) {
+            insetsFlags.appearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
             mViewRoot.mWindowAttributesChanged = true;
             mViewRoot.scheduleTraversals();
         }
     }
 
     @Override
+    public @Appearance int getSystemBarsAppearance() {
+        if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
+            // We only return the requested appearance, not the implied one.
+            return 0;
+        }
+        return mViewRoot.mWindowAttributes.insetsFlags.appearance;
+    }
+
+    @Override
     public void setSystemBarsBehavior(@Behavior int behavior) {
+        mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
         if (mViewRoot.mWindowAttributes.insetsFlags.behavior != behavior) {
             mViewRoot.mWindowAttributes.insetsFlags.behavior = behavior;
             mViewRoot.mWindowAttributesChanged = true;
             mViewRoot.scheduleTraversals();
         }
     }
+
+    @Override
+    public @Appearance int getSystemBarsBehavior() {
+        if ((mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) {
+            // We only return the requested behavior, not the implied one.
+            return 0;
+        }
+        return mViewRoot.mWindowAttributes.insetsFlags.behavior;
+    }
 }
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 8a1b45a..35a82b8 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -123,12 +123,19 @@
     }
 
     boolean applyLocalVisibilityOverride() {
+        final boolean isVisible = mState.getSource(mType).isVisible();
+        final boolean hasControl = mSourceControl != null;
+
+        // We still need to let the legacy app know the visibility change even if we don't have the
+        // control.
+        mController.updateCompatSysUiVisibility(
+                mType, hasControl ? mRequestedVisible : isVisible, hasControl);
 
         // If we don't have control, we are not able to change the visibility.
-        if (mSourceControl == null) {
+        if (!hasControl) {
             return false;
         }
-        if (mState.getSource(mType).isVisible() == mRequestedVisible) {
+        if (isVisible == mRequestedVisible) {
             return false;
         }
         mState.getSource(mType).setVisible(mRequestedVisible);
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index e33ca70..bd19799 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
@@ -143,7 +144,8 @@
     public WindowInsets calculateInsets(Rect frame, boolean isScreenRound,
             boolean alwaysConsumeSystemBars, DisplayCutout cutout,
             @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets,
-            int legacySoftInputMode, @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
+            int legacySoftInputMode, int legacySystemUiFlags,
+            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
         Insets[] typeInsetsMap = new Insets[Type.SIZE];
         Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
         boolean[] typeVisibilityMap = new boolean[SIZE];
@@ -186,7 +188,9 @@
         return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
                 alwaysConsumeSystemBars, cutout, softInputAdjustMode == SOFT_INPUT_ADJUST_RESIZE
                         ? systemBars() | ime()
-                        : systemBars());
+                        : systemBars(),
+                sNewInsetsMode == NEW_INSETS_MODE_FULL
+                        && (legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0);
     }
 
     public Rect calculateVisibleInsets(Rect frame, Rect legacyVisibleInsets,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6724e9d..377a764 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -22,6 +22,7 @@
 import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
 import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.WindowInsetsAnimationCallback.DISPATCH_MODE_CONTINUE_ON_SUBTREE;
 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
 
 import static java.lang.Math.max;
@@ -111,6 +112,7 @@
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.WindowInsetsAnimationCallback.AnimationBounds;
 import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimationCallback.DispatchMode;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -949,22 +951,14 @@
     private static boolean sAcceptZeroSizeDragShadow;
 
     /**
-     * Prior to Q, {@link #dispatchApplyWindowInsets} had some issues:
-     * <ul>
-     *     <li>The modified insets changed by {@link #onApplyWindowInsets} were passed to the
-     *     entire view hierarchy in prefix order, including siblings as well as siblings of parents
-     *     further down the hierarchy. This violates the basic concepts of the view hierarchy, and
-     *     thus, the hierarchical dispatching mechanism was hard to use for apps.</li>
-     *
-     *     <li>Dispatch was stopped after the insets were fully consumed. This is somewhat confusing
-     *     for developers, but more importantly, by adding more granular information to
-     *     {@link WindowInsets} it becomes really cumbersome to define what consumed actually means
-     *     </li>
-     * </ul>
-     *
+     * Prior to R, {@link #dispatchApplyWindowInsets} had an issue:
+     * <p>The modified insets changed by {@link #onApplyWindowInsets} were passed to the
+     * entire view hierarchy in prefix order, including siblings as well as siblings of parents
+     * further down the hierarchy. This violates the basic concepts of the view hierarchy, and
+     * thus, the hierarchical dispatching mechanism was hard to use for apps.
+     * <p>
      * In order to make window inset dispatching work properly, we dispatch window insets
-     * in the view hierarchy in a proper hierarchical manner and don't stop dispatching if the
-     * insets are consumed if this flag is set to {@code false}.
+     * in the view hierarchy in a proper hierarchical manner if this flag is set to {@code false}.
      */
     static boolean sBrokenInsetsDispatch;
 
@@ -4784,7 +4778,7 @@
     private CheckForTap mPendingCheckForTap = null;
     private PerformClick mPerformClick;
     private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
-
+    private SendAccessibilityEventThrottle mSendStateChangedAccessibilityEvent;
     private UnsetPressedState mUnsetPressedState;
 
     /**
@@ -5231,7 +5225,7 @@
             sAcceptZeroSizeDragShadow = targetSdkVersion < Build.VERSION_CODES.P;
 
             sBrokenInsetsDispatch = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
-                    || targetSdkVersion < Build.VERSION_CODES.Q;
+                    || targetSdkVersion < Build.VERSION_CODES.R;
 
             sBrokenWindowBackground = targetSdkVersion < Build.VERSION_CODES.Q;
 
@@ -8154,13 +8148,46 @@
         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
             dispatchPopulateAccessibilityEvent(event);
         }
-        // In the beginning we called #isShown(), so we know that getParent() is not null.
+        SendAccessibilityEventThrottle throttle = getThrottleForAccessibilityEvent(event);
+        if (throttle != null) {
+            throttle.post(event);
+        } else {
+            requestParentSendAccessibilityEvent(event);
+        }
+    }
+
+    private void requestParentSendAccessibilityEvent(AccessibilityEvent event) {
         ViewParent parent = getParent();
         if (parent != null) {
             getParent().requestSendAccessibilityEvent(this, event);
         }
     }
 
+    private SendAccessibilityEventThrottle getThrottleForAccessibilityEvent(
+            AccessibilityEvent event) {
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            if (mSendViewScrolledAccessibilityEvent == null) {
+                mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
+            }
+            return mSendViewScrolledAccessibilityEvent;
+        }
+        boolean isStateContentChanged = (event.getContentChangeTypes()
+                & AccessibilityEvent.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION) != 0;
+        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                && isStateContentChanged) {
+            if (mSendStateChangedAccessibilityEvent == null) {
+                mSendStateChangedAccessibilityEvent = new SendAccessibilityEventThrottle();
+            }
+            return mSendStateChangedAccessibilityEvent;
+        }
+        return null;
+    }
+
+    private void clearAccessibilityThrottles() {
+        cancel(mSendViewScrolledAccessibilityEvent);
+        cancel(mSendStateChangedAccessibilityEvent);
+    }
+
     /**
      * Dispatches an {@link AccessibilityEvent} to the {@link View} first and then
      * to its children for adding their text content to the event. Note that the
@@ -10381,8 +10408,12 @@
                 && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
-        notifyViewAccessibilityStateChangedIfNeeded(
-                AccessibilityEvent.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION);
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            AccessibilityEvent event = AccessibilityEvent.obtain();
+            event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+            event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION);
+            sendAccessibilityEventUnchecked(event);
+        }
     }
 
     /**
@@ -11100,7 +11131,10 @@
     /**
      * Sets a {@link WindowInsetsAnimationCallback} to be notified about animations of windows that
      * cause insets.
-     *
+     * <p>
+     * When setting a listener, it's {@link WindowInsetsAnimationCallback#getDispatchMode() dispatch
+     * mode} will be retrieved and recorded until another listener will be set.
+     * </p>
      * @param listener The listener to set.
      */
     public void setWindowInsetsAnimationCallback(@Nullable WindowInsetsAnimationCallback listener) {
@@ -15986,10 +16020,7 @@
      */
     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
         notifySubtreeAccessibilityStateChangedIfNeeded();
-
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            postSendViewScrolledAccessibilityEventCallback(l - oldl, t - oldt);
-        }
+        postSendViewScrolledAccessibilityEventCallback(l - oldl, t - oldt);
 
         mBackgroundSizeChanged = true;
         mDefaultFocusHighlightSizeChanged = true;
@@ -18712,10 +18743,13 @@
      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
      */
     private void postSendViewScrolledAccessibilityEventCallback(int dx, int dy) {
-        if (mSendViewScrolledAccessibilityEvent == null) {
-            mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            AccessibilityEvent event =
+                    AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
+            event.setScrollDeltaX(dx);
+            event.setScrollDeltaY(dy);
+            sendAccessibilityEventUnchecked(event);
         }
-        mSendViewScrolledAccessibilityEvent.post(dx, dy);
     }
 
     /**
@@ -20013,7 +20047,7 @@
         removeUnsetPressCallback();
         removeLongPressCallback();
         removePerformClickCallback();
-        cancel(mSendViewScrolledAccessibilityEvent);
+        clearAccessibilityThrottles();
         stopNestedScroll();
 
         // Anything that started animating right before detach should already
@@ -28997,49 +29031,67 @@
         }
     }
 
-    /**
-     * Resuable callback for sending
-     * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
-     */
-    private class SendViewScrolledAccessibilityEvent implements Runnable {
+    private class SendAccessibilityEventThrottle implements Runnable {
         public volatile boolean mIsPending;
-        public int mDeltaX;
-        public int mDeltaY;
+        private AccessibilityEvent mAccessibilityEvent;
 
-        public void post(int dx, int dy) {
-            mDeltaX += dx;
-            mDeltaY += dy;
+        public void post(AccessibilityEvent accessibilityEvent) {
+            updateWithAccessibilityEvent(accessibilityEvent);
             if (!mIsPending) {
                 mIsPending = true;
-                postDelayed(this, ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
+                postDelayed(this,
+                        ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
             }
         }
 
         @Override
         public void run() {
             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                AccessibilityEvent event = AccessibilityEvent.obtain(
-                        AccessibilityEvent.TYPE_VIEW_SCROLLED);
-                event.setScrollDeltaX(mDeltaX);
-                event.setScrollDeltaY(mDeltaY);
-                sendAccessibilityEventUnchecked(event);
+                requestParentSendAccessibilityEvent(mAccessibilityEvent);
             }
             reset();
         }
 
-        private void reset() {
+        public void updateWithAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
+            mAccessibilityEvent = accessibilityEvent;
+        }
+
+        public void reset() {
             mIsPending = false;
+            mAccessibilityEvent = null;
+        }
+
+    }
+
+    /**
+     * Resuable callback for sending
+     * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
+     */
+    private class SendViewScrolledAccessibilityEvent extends SendAccessibilityEventThrottle {
+        public int mDeltaX;
+        public int mDeltaY;
+
+        @Override
+        public void updateWithAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
+            super.updateWithAccessibilityEvent(accessibilityEvent);
+            mDeltaX += accessibilityEvent.getScrollDeltaX();
+            mDeltaY += accessibilityEvent.getScrollDeltaY();
+            accessibilityEvent.setScrollDeltaX(mDeltaX);
+            accessibilityEvent.setScrollDeltaY(mDeltaY);
+        }
+
+        @Override
+        public void reset() {
+            super.reset();
             mDeltaX = 0;
             mDeltaY = 0;
         }
     }
-
     /**
-     * Remove the pending callback for sending a
-     * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
+     * Remove the pending callback for sending a throttled accessibility event.
      */
     @UnsupportedAppUsage
-    private void cancel(@Nullable SendViewScrolledAccessibilityEvent callback) {
+    private void cancel(@Nullable SendAccessibilityEventThrottle callback) {
         if (callback == null || !callback.mIsPending) return;
         removeCallbacks(callback);
         callback.reset();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 047d7da..e6470a7 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -17,11 +17,14 @@
 package android.view;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
+import static android.view.WindowInsetsAnimationCallback.DISPATCH_MODE_CONTINUE_ON_SUBTREE;
+import static android.view.WindowInsetsAnimationCallback.DISPATCH_MODE_STOP;
 
 import android.animation.LayoutTransition;
 import android.annotation.CallSuper;
 import android.annotation.IdRes;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.annotation.UiThread;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -45,6 +48,7 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pools;
@@ -52,6 +56,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.view.WindowInsetsAnimationCallback.AnimationBounds;
+import android.view.WindowInsetsAnimationCallback.DispatchMode;
 import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -607,6 +612,13 @@
     int mChildUnhandledKeyListeners = 0;
 
     /**
+     * Current dispatch mode of animation events
+     *
+     * @see WindowInsetsAnimationCallback#getDispatchMode()
+     */
+    private @DispatchMode int mInsetsAnimationDispatchMode = DISPATCH_MODE_CONTINUE_ON_SUBTREE;
+
+    /**
      * Empty ActionMode used as a sentinel in recursive entries to startActionModeForChild.
      *
      * @see #startActionModeForChild(View, android.view.ActionMode.Callback)
@@ -7170,6 +7182,9 @@
     @Override
     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
         insets = super.dispatchApplyWindowInsets(insets);
+        if (insets.isConsumed()) {
+            return insets;
+        }
         if (View.sBrokenInsetsDispatch) {
             return brokenDispatchApplyWindowInsets(insets);
         } else {
@@ -7178,13 +7193,11 @@
     }
 
     private WindowInsets brokenDispatchApplyWindowInsets(WindowInsets insets) {
-        if (!insets.isConsumed()) {
-            final int count = getChildCount();
-            for (int i = 0; i < count; i++) {
-                insets = getChildAt(i).dispatchApplyWindowInsets(insets);
-                if (insets.isConsumed()) {
-                    break;
-                }
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            insets = getChildAt(i).dispatchApplyWindowInsets(insets);
+            if (insets.isConsumed()) {
+                break;
             }
         }
         return insets;
@@ -7199,9 +7212,20 @@
     }
 
     @Override
+    public void setWindowInsetsAnimationCallback(@Nullable WindowInsetsAnimationCallback listener) {
+        super.setWindowInsetsAnimationCallback(listener);
+        mInsetsAnimationDispatchMode = listener != null
+                ? listener.getDispatchMode()
+                : DISPATCH_MODE_CONTINUE_ON_SUBTREE;
+    }
+
+    @Override
     public void dispatchWindowInsetsAnimationPrepare(
             @NonNull InsetsAnimation animation) {
         super.dispatchWindowInsetsAnimationPrepare(animation);
+        if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
+            return;
+        }
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
             getChildAt(i).dispatchWindowInsetsAnimationPrepare(animation);
@@ -7212,7 +7236,10 @@
     @NonNull
     public AnimationBounds dispatchWindowInsetsAnimationStart(
             @NonNull InsetsAnimation animation, @NonNull AnimationBounds bounds) {
-        super.dispatchWindowInsetsAnimationStart(animation, bounds);
+        bounds = super.dispatchWindowInsetsAnimationStart(animation, bounds);
+        if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
+            return bounds;
+        }
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
             getChildAt(i).dispatchWindowInsetsAnimationStart(animation, bounds);
@@ -7224,6 +7251,9 @@
     @NonNull
     public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets) {
         insets = super.dispatchWindowInsetsAnimationProgress(insets);
+        if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
+            return insets;
+        }
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
             getChildAt(i).dispatchWindowInsetsAnimationProgress(insets);
@@ -7234,6 +7264,9 @@
     @Override
     public void dispatchWindowInsetsAnimationFinish(@NonNull InsetsAnimation animation) {
         super.dispatchWindowInsetsAnimationFinish(animation);
+        if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
+            return;
+        }
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
             getChildAt(i).dispatchWindowInsetsAnimationFinish(animation);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 17b945b..09ebd00 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -18,6 +18,8 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.View.PFLAG_DRAW_ANIMATION;
 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
 import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -25,15 +27,24 @@
 import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
 import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER;
 import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
+import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
@@ -105,6 +116,7 @@
 import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.TypedValue;
+import android.view.InsetsState.InternalInsetsType;
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl.Transaction;
 import android.view.View.AttachInfo;
@@ -417,12 +429,17 @@
 
     @UnsupportedAppUsage
     final View.AttachInfo mAttachInfo;
+    final SystemUiVisibilityInfo mCompatibleVisibilityInfo;
     InputQueue.Callback mInputQueueCallback;
     InputQueue mInputQueue;
     @UnsupportedAppUsage
     FallbackEventHandler mFallbackEventHandler;
     Choreographer mChoreographer;
 
+    // used in relayout to get SurfaceControl size
+    // for BLAST adapter surface setup
+    private final Point mSurfaceSize = new Point();
+
     final Rect mTempRect; // used in the transaction to not thrash the heap.
     final Rect mVisRect; // used to retrieve visible rect of focused view.
     private final Rect mTempBoundsRect = new Rect(); // used to set the size of the bounds surface.
@@ -674,6 +691,7 @@
         mAdded = false;
         mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
                 context);
+        mCompatibleVisibilityInfo = new SystemUiVisibilityInfo();
         mAccessibilityManager = AccessibilityManager.getInstance(context);
         mAccessibilityManager.addAccessibilityStateChangeListener(
                 mAccessibilityInteractionConnectionManager, mHandler);
@@ -1862,6 +1880,9 @@
             mAttachInfo.mSystemUiVisibility &= ~mAttachInfo.mDisabledSystemUiVisibility;
             WindowManager.LayoutParams params = mWindowAttributes;
             mAttachInfo.mSystemUiVisibility |= getImpliedSystemUiVisibility(params);
+            mCompatibleVisibilityInfo.globalVisibility =
+                    (mCompatibleVisibilityInfo.globalVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE)
+                            | (mAttachInfo.mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
             if (mAttachInfo.mKeepScreenOn != oldScreenOn
                     || mAttachInfo.mSystemUiVisibility != params.subtreeSystemUiVisibility
                     || mAttachInfo.mHasSystemUiListeners != params.hasSystemUiListeners) {
@@ -1887,6 +1908,38 @@
         return vis;
     }
 
+    /**
+     * Update the compatible system UI visibility for dispatching it to the legacy app.
+     *
+     * @param type Indicates which type of the insets source we are handling.
+     * @param visible True if the insets source is visible.
+     * @param hasControl True if we can control the insets source.
+     */
+    void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible,
+            boolean hasControl) {
+        if ((type != ITYPE_STATUS_BAR && type != ITYPE_NAVIGATION_BAR)
+                || ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
+            return;
+        }
+        final SystemUiVisibilityInfo info = mCompatibleVisibilityInfo;
+        final int systemUiFlag = type == ITYPE_STATUS_BAR
+                ? View.SYSTEM_UI_FLAG_FULLSCREEN
+                : View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+        final boolean wasVisible = (info.globalVisibility & systemUiFlag) == 0;
+        if (visible) {
+            info.globalVisibility &= ~systemUiFlag;
+            if (!wasVisible && hasControl) {
+                // The local system UI visibility can only be cleared while we have the control.
+                info.localChanges |= systemUiFlag;
+            }
+        } else {
+            info.globalVisibility |= systemUiFlag;
+        }
+        if (mAttachInfo.mGlobalSystemUiVisibility != info.globalVisibility) {
+            scheduleTraversals();
+        }
+    }
+
     @VisibleForTesting
     public static void adjustLayoutParamsForCompatibility(WindowManager.LayoutParams inOutParams) {
         if (sNewInsetsMode != NEW_INSETS_MODE_FULL) {
@@ -1897,10 +1950,28 @@
         final int type = inOutParams.type;
         final int adjust = inOutParams.softInputMode & SOFT_INPUT_MASK_ADJUST;
 
-        if ((sysUiVis & SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0) {
-            inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-        } else if ((sysUiVis & SYSTEM_UI_FLAG_IMMERSIVE) != 0) {
-            inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_BARS_BY_SWIPE;
+        if ((inOutParams.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
+            inOutParams.insetsFlags.appearance = 0;
+            if ((sysUiVis & SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
+                inOutParams.insetsFlags.appearance |= APPEARANCE_LOW_PROFILE_BARS;
+            }
+            if ((sysUiVis & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0) {
+                inOutParams.insetsFlags.appearance |= APPEARANCE_LIGHT_STATUS_BARS;
+            }
+            if ((sysUiVis & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0) {
+                inOutParams.insetsFlags.appearance |= APPEARANCE_LIGHT_NAVIGATION_BARS;
+            }
+        }
+
+        if ((inOutParams.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) {
+            if ((sysUiVis & SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0
+                    || (flags & FLAG_FULLSCREEN) != 0) {
+                inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+            } else if ((sysUiVis & SYSTEM_UI_FLAG_IMMERSIVE) != 0) {
+                inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_BARS_BY_SWIPE;
+            } else {
+                inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_BARS_BY_TOUCH;
+            }
         }
 
         if ((inOutParams.privateFlags & PRIVATE_FLAG_FIT_INSETS_CONTROLLED) != 0) {
@@ -2082,7 +2153,9 @@
             mLastWindowInsets = mInsetsController.calculateInsets(
                     mContext.getResources().getConfiguration().isScreenRound(),
                     mAttachInfo.mAlwaysConsumeSystemBars, displayCutout,
-                    contentInsets, stableInsets, mWindowAttributes.softInputMode);
+                    contentInsets, stableInsets, mWindowAttributes.softInputMode,
+                    (mWindowAttributes.systemUiVisibility
+                            | mWindowAttributes.subtreeSystemUiVisibility));
         }
         return mLastWindowInsets;
     }
@@ -2303,6 +2376,11 @@
             mAttachInfo.mForceReportNewAttributes = false;
             params = lp;
         }
+        if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
+            adjustLayoutParamsForCompatibility(lp);
+            controlInsetsForCompatibility(lp);
+            handleDispatchSystemUiVisibilityChanged(mCompatibleVisibilityInfo);
+        }
 
         if (mFirst || mAttachInfo.mViewVisibilityChanged) {
             mAttachInfo.mViewVisibilityChanged = false;
@@ -2396,8 +2474,6 @@
                     && !PixelFormat.formatHasAlpha(params.format)) {
                 params.format = PixelFormat.TRANSLUCENT;
             }
-            adjustLayoutParamsForCompatibility(params);
-            controlInsetsForCompatibility(params);
         }
 
         if (mFirst || windowShouldResize || insetsChanged ||
@@ -7096,7 +7172,7 @@
     }
 
     public void handleDispatchSystemUiVisibilityChanged(SystemUiVisibilityInfo args) {
-        if (mSeq != args.seq) {
+        if (mSeq != args.seq && sNewInsetsMode != NEW_INSETS_MODE_FULL) {
             // The sequence has changed, so we need to update our value and make
             // sure to do a traversal afterward so the window manager is given our
             // most recent data.
@@ -7107,6 +7183,7 @@
         if (mView == null) return;
         if (args.localChanges != 0) {
             mView.updateLocalSystemUiVisibility(args.localValue, args.localChanges);
+            args.localChanges = 0;
         }
 
         int visibility = args.globalVisibility&View.SYSTEM_UI_CLEARABLE_FLAGS;
@@ -7260,14 +7337,13 @@
                 insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                 mTmpFrame, mPendingContentInsets, mPendingVisibleInsets,
                 mPendingStableInsets, mPendingBackDropFrame, mPendingDisplayCutout,
-                mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
+                mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mSurfaceSize);
         if (mSurfaceControl.isValid()) {
             if (!WindowManagerGlobal.USE_BLAST_ADAPTER) {
                 mSurface.copyFrom(mSurfaceControl);
             } else {
-                mSurface.transferFrom(getOrCreateBLASTSurface(
-                    (int) (mView.getMeasuredWidth() * appScale + 0.5f),
-                    (int) (mView.getMeasuredHeight() * appScale + 0.5f)));
+                mSurface.transferFrom(getOrCreateBLASTSurface(mSurfaceSize.x,
+                        mSurfaceSize.y));
             }
         } else {
             destroySurface();
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 9291b56..0a2a45b 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -27,6 +27,7 @@
 import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
 import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT;
 import static android.view.WindowInsets.Type.all;
+import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.indexOf;
 import static android.view.WindowInsets.Type.systemBars;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
@@ -41,11 +42,13 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.util.SparseArray;
+import android.view.View.OnApplyWindowInsetsListener;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethod;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
@@ -91,15 +94,23 @@
     private final boolean mDisplayCutoutConsumed;
 
     private final int mCompatInsetTypes;
+    private final boolean mCompatIgnoreVisibility;
 
     /**
-     * Since new insets may be added in the future that existing apps couldn't
-     * know about, this fully empty constant shouldn't be made available to apps
-     * since it would allow them to inadvertently consume unknown insets by returning it.
-     * @hide
+     * A {@link WindowInsets} instance for which {@link #isConsumed()} returns {@code true}.
+     * <p>
+     * This can be used during insets dispatch in the view hierarchy by returning this value from
+     * {@link View#onApplyWindowInsets(WindowInsets)} or
+     * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets)} to stop dispatch
+     * the insets to its children to avoid traversing the entire view hierarchy.
+     * <p>
+     * The application should return this instance once it has taken care of all insets on a certain
+     * level in the view hierarchy, and doesn't need to dispatch to its children anymore for better
+     * performance.
+     *
+     * @see #isConsumed()
      */
-    @UnsupportedAppUsage
-    public static final WindowInsets CONSUMED;
+    public static final @NonNull WindowInsets CONSUMED;
 
     static {
         CONSUMED = new WindowInsets((Rect) null, null, false, false, null);
@@ -117,7 +128,8 @@
             boolean isRound, boolean alwaysConsumeSystemBars, DisplayCutout displayCutout) {
         this(createCompatTypeMap(systemWindowInsetsRect), createCompatTypeMap(stableInsetsRect),
                 createCompatVisibilityMap(createCompatTypeMap(systemWindowInsetsRect)),
-                isRound, alwaysConsumeSystemBars, displayCutout, systemBars());
+                isRound, alwaysConsumeSystemBars, displayCutout, systemBars(),
+                false /* compatIgnoreVisibility */);
     }
 
     /**
@@ -136,7 +148,8 @@
             @Nullable Insets[] typeMaxInsetsMap,
             boolean[] typeVisibilityMap,
             boolean isRound,
-            boolean alwaysConsumeSystemBars, DisplayCutout displayCutout, int compatInsetTypes) {
+            boolean alwaysConsumeSystemBars, DisplayCutout displayCutout, int compatInsetTypes,
+            boolean compatIgnoreVisibility) {
         mSystemWindowInsetsConsumed = typeInsetsMap == null;
         mTypeInsetsMap = mSystemWindowInsetsConsumed
                 ? new Insets[SIZE]
@@ -151,6 +164,7 @@
         mIsRound = isRound;
         mAlwaysConsumeSystemBars = alwaysConsumeSystemBars;
         mCompatInsetTypes = compatInsetTypes;
+        mCompatIgnoreVisibility = compatIgnoreVisibility;
 
         mDisplayCutoutConsumed = displayCutout == null;
         mDisplayCutout = (mDisplayCutoutConsumed || displayCutout.isEmpty())
@@ -167,7 +181,8 @@
                 src.mStableInsetsConsumed ? null : src.mTypeMaxInsetsMap,
                 src.mTypeVisibilityMap, src.mIsRound,
                 src.mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(src),
-                src.mCompatInsetTypes);
+                src.mCompatInsetTypes,
+                src.mCompatIgnoreVisibility);
     }
 
     private static DisplayCutout displayCutoutCopyConstructorArgument(WindowInsets w) {
@@ -219,7 +234,7 @@
     @UnsupportedAppUsage
     public WindowInsets(Rect systemWindowInsets) {
         this(createCompatTypeMap(systemWindowInsets), null, new boolean[SIZE], false, false, null,
-                systemBars());
+                systemBars(), false /* compatIgnoreVisibility */);
     }
 
     /**
@@ -239,7 +254,8 @@
     /**
      * @hide
      */
-    static void assignCompatInsets(Insets[] typeInsetsMap, Rect insets) {
+    @VisibleForTesting
+    public static void assignCompatInsets(Insets[] typeInsetsMap, Rect insets) {
         typeInsetsMap[indexOf(STATUS_BARS)] = Insets.of(0, insets.top, 0, 0);
         typeInsetsMap[indexOf(NAVIGATION_BARS)] =
                 Insets.of(insets.left, 0, insets.right, insets.bottom);
@@ -288,7 +304,15 @@
      */
     @NonNull
     public Insets getSystemWindowInsets() {
-        return getInsets(mTypeInsetsMap, mCompatInsetTypes);
+        Insets result = mCompatIgnoreVisibility
+                ? getMaxInsets(mCompatInsetTypes & ~ime())
+                : getInsets(mCompatInsetTypes);
+
+        // We can't query max insets for IME, so we need to add it manually after.
+        if ((mCompatInsetTypes & ime()) != 0 && mCompatIgnoreVisibility) {
+            result = Insets.max(result, getInsets(ime()));
+        }
+        return result;
     }
 
     /**
@@ -440,7 +464,11 @@
      * Returns a copy of this WindowInsets with the cutout fully consumed.
      *
      * @return A modified copy of this WindowInsets
+     * @deprecated Consuming of different parts individually of a {@link WindowInsets} instance is
+     * deprecated, since {@link WindowInsets} contains many different insets. Use {@link #CONSUMED}
+     * instead to stop dispatching insets.
      */
+    @Deprecated
     @NonNull
     public WindowInsets consumeDisplayCutout() {
         return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap,
@@ -448,7 +476,7 @@
                 mTypeVisibilityMap,
                 mIsRound, mAlwaysConsumeSystemBars,
                 null /* displayCutout */,
-                mCompatInsetTypes);
+                mCompatInsetTypes, mCompatIgnoreVisibility);
     }
 
 
@@ -488,14 +516,18 @@
      * Returns a copy of this WindowInsets with the system window insets fully consumed.
      *
      * @return A modified copy of this WindowInsets
+     * @deprecated Consuming of different parts individually of a {@link WindowInsets} instance is
+     * deprecated, since {@link WindowInsets} contains many different insets. Use {@link #CONSUMED}
+     * instead to stop dispatching insets.
      */
+    @Deprecated
     @NonNull
     public WindowInsets consumeSystemWindowInsets() {
-        return new WindowInsets(null, mStableInsetsConsumed ? null : mTypeMaxInsetsMap,
+        return new WindowInsets(null, null,
                 mTypeVisibilityMap,
                 mIsRound, mAlwaysConsumeSystemBars,
                 displayCutoutCopyConstructorArgument(this),
-                mCompatInsetTypes);
+                mCompatInsetTypes, mCompatIgnoreVisibility);
     }
 
     // TODO(b/119190588): replace @code with @link below
@@ -738,13 +770,14 @@
      * Returns a copy of this WindowInsets with the stable insets fully consumed.
      *
      * @return A modified copy of this WindowInsets
+     * @deprecated Consuming of different parts individually of a {@link WindowInsets} instance is
+     * deprecated, since {@link WindowInsets} contains many different insets. Use {@link #CONSUMED}
+     * instead to stop dispatching insets.
      */
+    @Deprecated
     @NonNull
     public WindowInsets consumeStableInsets() {
-        return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap, null,
-                mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars,
-                displayCutoutCopyConstructorArgument(this),
-                mCompatInsetTypes);
+        return consumeSystemWindowInsets();
     }
 
     /**
@@ -829,7 +862,7 @@
                         : mDisplayCutout == null
                                 ? DisplayCutout.NO_CUTOUT
                                 : mDisplayCutout.inset(left, top, right, bottom),
-                mCompatInsetTypes);
+                mCompatInsetTypes, mCompatIgnoreVisibility);
     }
 
     @Override
@@ -1147,7 +1180,7 @@
             return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap,
                     mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap,
                     mIsRound, mAlwaysConsumeSystemBars, mDisplayCutout,
-                    systemBars());
+                    systemBars(), false /* compatIgnoreVisibility */);
         }
     }
 
diff --git a/core/java/android/view/WindowInsetsAnimationCallback.java b/core/java/android/view/WindowInsetsAnimationCallback.java
index e84c3e3..53d4939 100644
--- a/core/java/android/view/WindowInsetsAnimationCallback.java
+++ b/core/java/android/view/WindowInsetsAnimationCallback.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.FloatRange;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Insets;
@@ -24,6 +25,9 @@
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.animation.Interpolator;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Interface that allows the application to listen to animation events for windows that cause
  * insets.
@@ -31,6 +35,52 @@
 public interface WindowInsetsAnimationCallback {
 
     /**
+     * Return value for {@link #getDispatchMode()}: Dispatching of animation events should
+     * stop at this level in the view hierarchy, and no animation events should be dispatch to the
+     * subtree of the view hierarchy.
+     */
+    int DISPATCH_MODE_STOP = 0;
+
+    /**
+     * Return value for {@link #getDispatchMode()}: Dispatching of animation events should
+     * continue in the view hierarchy.
+     */
+    int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1;
+
+    /** @hide */
+    @IntDef(prefix = { "DISPATCH_MODE_" }, value = {
+            DISPATCH_MODE_STOP,
+            DISPATCH_MODE_CONTINUE_ON_SUBTREE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DispatchMode {}
+
+    /**
+     * Retrieves the dispatch mode of this listener. Dispatch of the all animation events is
+     * hierarchical: It will starts at the root of the view hierarchy and then traverse it and
+     * invoke the callback of the specific {@link View} that is being traversed.
+     * The method may return either {@link #DISPATCH_MODE_CONTINUE_ON_SUBTREE} to indicate that
+     * animation events should be propagated to the subtree of the view hierarchy, or
+     * {@link #DISPATCH_MODE_STOP} to stop dispatching. In that case, all animation callbacks
+     * related to the animation passed in will be stopped from propagating to the subtree of the
+     * hierarchy.
+     * <p>
+     * Note that this method will only be invoked once when
+     * {@link View#setWindowInsetsAnimationCallback setting the listener} and then the framework
+     * will use the recorded result.
+     * <p>
+     * Also note that returning {@link #DISPATCH_MODE_STOP} here behaves the same way as returning
+     * {@link WindowInsets#CONSUMED} during the regular insets dispatch in
+     * {@link View#onApplyWindowInsets}.
+     *
+     * @return Either {@link #DISPATCH_MODE_CONTINUE_ON_SUBTREE} to indicate that dispatching of
+     *         animation events will continue to the subtree of the view hierarchy, or
+     *         {@link #DISPATCH_MODE_STOP} to indicate that animation events will stop dispatching.
+     */
+    @DispatchMode
+    int getDispatchMode();
+
+    /**
      * Called when an insets animation is about to start and before the views have been laid out in
      * the end state of the animation. The ordering of events during an insets animation is the
      * following:
@@ -75,10 +125,11 @@
      * <p>
      * Note that, like {@link #onProgress}, dispatch of the animation start event is hierarchical:
      * It will starts at the root of the view hierarchy and then traverse it and invoke the callback
-     * of the specific {@link View} that is being traversed. The method my return a modified
+     * of the specific {@link View} that is being traversed. The method may return a modified
      * instance of the bounds by calling {@link AnimationBounds#inset} to indicate that a part of
      * the insets have been used to offset or clip its children, and the children shouldn't worry
-     * about that part anymore.
+     * about that part anymore. Furthermore, if {@link #getDispatchMode()} returns
+     * {@link #DISPATCH_MODE_STOP}, children of this view will not receive the callback anymore.
      *
      * @param animation The animation that is about to start.
      * @param bounds The bounds in which animation happens.
@@ -102,7 +153,9 @@
      * The method may return a modified instance by calling
      * {@link WindowInsets#inset(int, int, int, int)} to indicate that a part of the insets have
      * been used to offset or clip its children, and the children shouldn't worry about that part
-     * anymore.
+     * anymore. Furthermore, if {@link #getDispatchMode()} returns
+     * {@link #DISPATCH_MODE_STOP}, children of this view will not receive the callback anymore.
+     *
      * TODO: Introduce a way to map (type -> InsetAnimation) so app developer can query animation
      *  for a given type e.g. callback.getAnimation(type) OR controller.getAnimation(type).
      *  Or on the controller directly?
@@ -237,6 +290,7 @@
      * Class representing the range of an {@link InsetsAnimation}
      */
     final class AnimationBounds {
+
         private final Insets mLowerBound;
         private final Insets mUpperBound;
 
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 9d7f292..f292ca4 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -29,7 +29,7 @@
 /**
  * Interface to control windows that generate insets.
  *
- * TODO Needs more information and examples once the API is more baked.
+ * TODO(118118435): Needs more information and examples once the API is more baked.
  */
 public interface WindowInsetsController {
 
@@ -205,21 +205,47 @@
 
     /**
      * Controls the appearance of system bars.
+     * <p>
+     * For example, the following statement adds {@link #APPEARANCE_LIGHT_STATUS_BARS}:
+     * <pre>
+     * setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS)
+     * </pre>
+     * And the following statement clears it:
+     * <pre>
+     * setSystemBarsAppearance(0, APPEARANCE_LIGHT_STATUS_BARS)
+     * </pre>
      *
      * @param appearance Bitmask of {@link Appearance} flags.
-     * @see Appearance
+     * @param mask Specifies which flags of appearance should be changed.
+     * @see #getSystemBarsAppearance
      */
-    void setSystemBarsAppearance(@Appearance int appearance);
+    void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask);
+
+    /**
+     * Retrieves the requested appearance of system bars.
+     *
+     * @return The requested bitmask of system bar appearance controlled by this window.
+     * @see #setSystemBarsAppearance(int, int)
+     */
+    @Appearance int getSystemBarsAppearance();
 
     /**
      * Controls the behavior of system bars.
      *
      * @param behavior Determines how the bars behave when being hidden by the application.
-     * @see Behavior
+     * @see #getSystemBarsBehavior
      */
     void setSystemBarsBehavior(@Behavior int behavior);
 
     /**
+     * Retrieves the requested behavior of system bars.
+     *
+     * @return the system bar behavior controlled by this window.
+     * @see #setSystemBarsBehavior(int)
+     */
+    @Behavior int getSystemBarsBehavior();
+
+    /**
      * @hide
      */
     InsetsState getState();
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f7d9706..cd9dee4 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1131,6 +1131,15 @@
         public static final int TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 39;
 
         /**
+         * Window type: the notification shade and keyguard. There can be only one status bar
+         * window; it is placed at the top of the screen, and all other
+         * windows are shifted down so they are below it.
+         * In multiuser systems shows on all users' windows.
+         * @hide
+         */
+        public static final int TYPE_NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40;
+
+        /**
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
@@ -1732,14 +1741,6 @@
         public static final int PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100;
 
         /**
-         * Flag whether the current window is a keyguard window, meaning that it will hide all other
-         * windows behind it except for windows with flag {@link #FLAG_SHOW_WHEN_LOCKED} set.
-         * Further, this can only be set by {@link LayoutParams#TYPE_STATUS_BAR}.
-         * {@hide}
-         */
-        public static final int PRIVATE_FLAG_KEYGUARD = 0x00000400;
-
-        /**
          * Flag that prevents the wallpaper behind the current window from receiving touch events.
          *
          * {@hide}
@@ -1748,12 +1749,12 @@
 
         /**
          * Flag to force the status bar window to be visible all the time. If the bar is hidden when
-         * this flag is set it will be shown again and the bar will have a transparent background.
+         * this flag is set it will be shown again.
          * This can only be set by {@link LayoutParams#TYPE_STATUS_BAR}.
          *
          * {@hide}
          */
-        public static final int PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT = 0x00001000;
+        public static final int PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR = 0x00001000;
 
         /**
          * Flag indicating that the x, y, width, and height members should be
@@ -1856,18 +1857,32 @@
         public static final int PRIVATE_FLAG_USE_BLAST = 0x02000000;
 
         /**
+         * Flag to indicate that the window is controlling the appearance of system bars. So we
+         * don't need to adjust it by reading its system UI flags for compatibility.
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_APPEARANCE_CONTROLLED = 0x04000000;
+
+        /**
+         * Flag to indicate that the window is controlling the behavior of system bars. So we don't
+         * need to adjust it by reading its window flags or system UI flags for compatibility.
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_BEHAVIOR_CONTROLLED = 0x08000000;
+
+        /**
          * Flag to indicate that the window is controlling how it fits window insets on its own.
          * So we don't need to adjust its attributes for fitting window insets.
          * @hide
          */
-        public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 0x04000000;
+        public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 0x10000000;
 
         /**
          * Flag to indicate that the window only draws the bottom bar background so that we don't
          * extend it to system bar areas at other sides.
          * @hide
          */
-        public static final int PRIVATE_FLAG_ONLY_DRAW_BOTTOM_BAR_BACKGROUND = 0x08000000;
+        public static final int PRIVATE_FLAG_ONLY_DRAW_BOTTOM_BAR_BACKGROUND = 0x20000000;
 
         /**
          * An internal annotation for flags that can be specified to {@link #softInputMode}.
@@ -1917,17 +1932,13 @@
                         equals = PRIVATE_FLAG_SYSTEM_ERROR,
                         name = "SYSTEM_ERROR"),
                 @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_KEYGUARD,
-                        equals = PRIVATE_FLAG_KEYGUARD,
-                        name = "KEYGUARD"),
-                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
                         equals = PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
                         name = "DISABLE_WALLPAPER_TOUCH_EVENTS"),
                 @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT,
-                        equals = PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT,
-                        name = "FORCE_STATUS_BAR_VISIBLE_TRANSPARENT"),
+                        mask = PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
+                        equals = PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
+                        name = "FORCE_STATUS_BAR_VISIBLE"),
                 @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_PRESERVE_GEOMETRY,
                         equals = PRIVATE_FLAG_PRESERVE_GEOMETRY,
@@ -1973,6 +1984,14 @@
                         equals = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
                         name = "COLOR_SPACE_AGNOSTIC"),
                 @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
+                        equals = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
+                        name = "APPEARANCE_CONTROLLED"),
+                @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
+                        equals = PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
+                        name = "BEHAVIOR_CONTROLLED"),
+                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
                         equals = PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
                         name = "FIT_INSETS_CONTROLLED"),
@@ -2402,7 +2421,8 @@
                 flag = true,
                 value = {LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT,
                         LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,
-                        LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER})
+                        LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER,
+                        LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS})
         @interface LayoutInDisplayCutoutMode {}
 
         /**
@@ -2414,6 +2434,7 @@
          * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
          * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
          * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
+         * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
          * @see DisplayCutout
          * @see android.R.attr#windowLayoutInDisplayCutoutMode
          *         android:windowLayoutInDisplayCutoutMode
@@ -2447,13 +2468,6 @@
         public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;
 
         /**
-         * @deprecated use {@link #LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES}
-         * @hide
-         */
-        @Deprecated
-        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 1;
-
-        /**
          * The window is always allowed to extend into the {@link DisplayCutout} areas on the short
          * edges of the screen.
          *
@@ -2516,6 +2530,25 @@
          */
         public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2;
 
+        /**
+         * The window is always allowed to extend into the {@link DisplayCutout} areas on the all
+         * edges of the screen.
+         *
+         * <p>
+         * The window must make sure that no important content overlaps with the
+         * {@link DisplayCutout}.
+         *
+         * <p>
+         * In this mode, the window extends under cutouts on the all edges of the display in both
+         * portrait and landscape, regardless of whether the window is hiding the system bars.
+         *
+         * @see DisplayCutout
+         * @see WindowInsets#getDisplayCutout()
+         * @see #layoutInDisplayCutoutMode
+         * @see android.R.attr#windowLayoutInDisplayCutoutMode
+         *         android:windowLayoutInDisplayCutoutMode
+         */
+        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 3;
 
         /**
          * When this window has focus, disable touch pad pointer gesture processing.
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 1312a9b..9f27848 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Configuration;
 import android.graphics.PixelFormat;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -159,7 +160,8 @@
             Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
             Rect outStableInsets, Rect outBackdropFrame,
             DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
-            SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
+            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+            Point outSurfaceSize) {
         State state = null;
         synchronized (this) {
             state = mStateForWindow.get(window.asBinder());
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index b891af5..513e72f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.AppGlobals;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
 import android.app.RemoteAction;
@@ -384,6 +385,10 @@
 
     private final SuggestionHelper mSuggestionHelper = new SuggestionHelper();
 
+    // Specifies whether the cursor control feature set is enabled.
+    // This can only be true if the text view is editable.
+    private final boolean mCursorControlEnabled;
+
     Editor(TextView textView) {
         mTextView = textView;
         // Synchronize the filter list, which places the undo input filter at the end.
@@ -397,6 +402,13 @@
                     Magnifier.createBuilderWithOldMagnifierDefaults(mTextView).build();
             mMagnifierAnimator = new MagnifierMotionAnimator(magnifier);
         }
+
+        mCursorControlEnabled = AppGlobals.getIntCoreSetting(
+                WidgetFlags.KEY_ENABLE_CURSOR_CONTROL , 0) != 0;
+        if (TextView.DEBUG_CURSOR) {
+            logCursor("Editor", "Cursor control is %s.",
+                    mCursorControlEnabled ? "enabled" : "disabled");
+        }
     }
 
     ParcelableParcel saveInstanceState() {
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index d119b2e..4e705db 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -66,6 +66,10 @@
  * <p>
  * The easiest way to use this class is to call one of the static methods that constructs
  * everything you need and returns a new Toast object.
+ * <p>
+ * Note that
+ * <a href="{@docRoot}reference/com/google/android/material/snackbar/Snackbar">Snackbars</a> are
+ * preferred for brief messages while the app is in the foreground.
  *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
@@ -169,8 +173,16 @@
 
     /**
      * Set the view to show.
+     *
      * @see #getView
+     * @deprecated Custom toast views are deprecated. Apps can create a standard text toast with the
+     *      {@link #makeText(Context, CharSequence, int)} method, or use a
+     *      <a href="{@docRoot}reference/com/google/android/material/snackbar/Snackbar">Snackbar</a>
+     *      when in the foreground. Starting from Android {@link Build.VERSION_CODES#R}, apps
+     *      targeting API level {@link Build.VERSION_CODES#R} or higher that are in the background
+     *      will not have custom toast views displayed.
      */
+    @Deprecated
     public void setView(View view) {
         mIsCustomToast = true;
         mNextView = view;
@@ -178,7 +190,14 @@
 
     /**
      * Return the view.
+     *
      * @see #setView
+     * @deprecated Custom toast views are deprecated. Apps can create a standard text toast with the
+     *      {@link #makeText(Context, CharSequence, int)} method, or use a
+     *      <a href="{@docRoot}reference/com/google/android/material/snackbar/Snackbar">Snackbar</a>
+     *      when in the foreground. Starting from Android {@link Build.VERSION_CODES#R}, apps
+     *      targeting API level {@link Build.VERSION_CODES#R} or higher that are in the background
+     *      will not have custom toast views displayed.
      */
     public View getView() {
         mIsCustomToast = true;
diff --git a/core/java/android/widget/WidgetFlags.java b/core/java/android/widget/WidgetFlags.java
new file mode 100644
index 0000000..fa1e498d
--- /dev/null
+++ b/core/java/android/widget/WidgetFlags.java
@@ -0,0 +1,40 @@
+/*
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+package android.widget;
+
+/**
+ * Keeps the flags related to the Widget namespace in {@link DeviceConfig}.
+ *
+ * @hide
+ */
+public final class WidgetFlags {
+
+    /**
+     * Whether the cursor control feature set is enabled.
+     * TODO: Makes this flag key visible to webview/chrome.
+     */
+    public static final String ENABLE_CURSOR_CONTROL =
+            "CursorControlFeature__enable_cursor_control";
+
+    /**
+     * The key name used in app core settings for enable cursor control.
+     */
+    public static final String KEY_ENABLE_CURSOR_CONTROL = "widget__enable_cursor_control";
+
+    private WidgetFlags() {
+    }
+}
diff --git a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
index 457c033..384275f 100644
--- a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
@@ -27,6 +27,7 @@
 import static com.android.internal.app.AccessibilityButtonChooserActivity.WhiteListingFeatureElementIndex.ICON_ID;
 import static com.android.internal.app.AccessibilityButtonChooserActivity.WhiteListingFeatureElementIndex.LABEL_ID;
 import static com.android.internal.app.AccessibilityButtonChooserActivity.WhiteListingFeatureElementIndex.SETTINGS_KEY;
+import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.IntDef;
@@ -75,15 +76,10 @@
     private static final char SERVICES_SEPARATOR = ':';
     private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
             new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR);
-    @UserShortcutType
-    private static final int ACCESSIBILITY_BUTTON_USER_TYPE = convertToUserType(
-            ACCESSIBILITY_BUTTON);
-    @UserShortcutType
-    private static final int ACCESSIBILITY_SHORTCUT_KEY_USER_TYPE = convertToUserType(
-            ACCESSIBILITY_SHORTCUT_KEY);
-
     @ShortcutType
     private int mShortcutType;
+    @UserShortcutType
+    private int mShortcutUserType;
     private final List<AccessibilityButtonTarget> mTargets = new ArrayList<>();
     private AlertDialog mAlertDialog;
     private TargetAdapter mTargetAdapter;
@@ -213,11 +209,12 @@
         }
 
         mShortcutType = getIntent().getIntExtra(AccessibilityManager.EXTRA_SHORTCUT_TYPE,
-                ACCESSIBILITY_BUTTON);
-        if ((mShortcutType != ACCESSIBILITY_BUTTON)
-                && (mShortcutType != ACCESSIBILITY_SHORTCUT_KEY)) {
-            throw new IllegalStateException("Unexpected shortcut type: " + mShortcutType);
-        }
+                /* unexpectedShortcutType */ -1);
+        final boolean existInShortcutType = (mShortcutType == ACCESSIBILITY_BUTTON)
+                || (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY);
+        checkArgument(existInShortcutType, "Unexpected shortcut type: " + mShortcutType);
+
+        mShortcutUserType = convertToUserType(mShortcutType);
 
         mTargets.addAll(getServiceTargets(this, mShortcutType));
 
@@ -343,13 +340,11 @@
         }
     }
 
-    private void disableService(ComponentName componentName) {
-        final String componentId = componentName.flattenToString();
-
+    private void disableService(String componentId) {
         if (isWhiteListingService(componentId)) {
-            setWhiteListingServiceEnabled(componentName.flattenToString(),
-                    /* settingsValueOff */ 0);
+            setWhiteListingServiceEnabled(componentId, /* settingsValueOff */ 0);
         } else {
+            final ComponentName componentName = ComponentName.unflattenFromString(componentId);
             setAccessibilityServiceState(this, componentName, /* enabled= */ false);
         }
     }
@@ -620,18 +615,17 @@
 
     private void onTargetDeleted(AdapterView<?> parent, View view, int position, long id) {
         final AccessibilityButtonTarget target = mTargets.get(position);
-        final ComponentName targetComponentName =
-                ComponentName.unflattenFromString(target.getId());
+        final String componentId = target.getId();
 
         switch (target.getFragmentType()) {
             case AccessibilityServiceFragmentType.LEGACY:
-                onLegacyTargetDeleted(targetComponentName);
+                onLegacyTargetDeleted(position, componentId);
                 break;
             case AccessibilityServiceFragmentType.INVISIBLE:
-                onInvisibleTargetDeleted(targetComponentName);
+                onInvisibleTargetDeleted(position, componentId);
                 break;
             case AccessibilityServiceFragmentType.INTUITIVE:
-                onIntuitiveTargetDeleted(targetComponentName);
+                onIntuitiveTargetDeleted(position, componentId);
                 break;
             case AccessibilityServiceFragmentType.BOUNCE:
                 // Do nothing
@@ -640,44 +634,36 @@
                 throw new IllegalStateException("Unexpected fragment type");
         }
 
-        mTargets.remove(position);
-        mTargetAdapter.notifyDataSetChanged();
-
         if (mTargets.isEmpty()) {
             mAlertDialog.dismiss();
         }
     }
 
-    private void onLegacyTargetDeleted(ComponentName componentName) {
+    private void onLegacyTargetDeleted(int position, String componentId) {
         if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
-            optOutValueFromSettings(this, ACCESSIBILITY_SHORTCUT_KEY_USER_TYPE, componentName);
+            optOutValueFromSettings(this, mShortcutUserType, componentId);
+
+            mTargets.remove(position);
+            mTargetAdapter.notifyDataSetChanged();
         }
     }
 
-    private void onInvisibleTargetDeleted(ComponentName componentName) {
-        if (mShortcutType == ACCESSIBILITY_BUTTON) {
-            optOutValueFromSettings(this, ACCESSIBILITY_BUTTON_USER_TYPE, componentName);
+    private void onInvisibleTargetDeleted(int position, String componentId) {
+        optOutValueFromSettings(this, mShortcutUserType, componentId);
 
-            if (!hasValueInSettings(this,
-                    ACCESSIBILITY_SHORTCUT_KEY_USER_TYPE, componentName)) {
-                disableService(componentName);
-            }
-        } else if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
-            optOutValueFromSettings(this, ACCESSIBILITY_SHORTCUT_KEY_USER_TYPE, componentName);
-
-            if (!hasValueInSettings(this,
-                    ACCESSIBILITY_BUTTON_USER_TYPE, componentName)) {
-                disableService(componentName);
-            }
+        final int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE;
+        if (!hasValuesInSettings(this, shortcutTypes, componentId)) {
+            disableService(componentId);
         }
+
+        mTargets.remove(position);
+        mTargetAdapter.notifyDataSetChanged();
     }
 
-    private void onIntuitiveTargetDeleted(ComponentName componentName) {
-        if (mShortcutType == ACCESSIBILITY_BUTTON) {
-            optOutValueFromSettings(this, ACCESSIBILITY_BUTTON_USER_TYPE, componentName);
-        } else if (mShortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
-            optOutValueFromSettings(this, ACCESSIBILITY_SHORTCUT_KEY_USER_TYPE, componentName);
-        }
+    private void onIntuitiveTargetDeleted(int position, String componentId) {
+        optOutValueFromSettings(this, mShortcutUserType, componentId);
+        mTargets.remove(position);
+        mTargetAdapter.notifyDataSetChanged();
     }
 
     private void onCancelButtonClicked() {
@@ -786,10 +772,10 @@
      *
      * @param context The current context.
      * @param shortcutType The preferred shortcut type user selected.
-     * @param componentName The component name that need to be opted out from Settings.
+     * @param componentId The component id that need to be opted out from Settings.
      */
     private void optOutValueFromSettings(
-            Context context, @UserShortcutType int shortcutType, ComponentName componentName) {
+            Context context, @UserShortcutType int shortcutType, String componentId) {
         final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
         final String targetsKey = convertToKey(shortcutType);
         final String targetsValue = Settings.Secure.getString(context.getContentResolver(),
@@ -801,26 +787,47 @@
 
         sStringColonSplitter.setString(targetsValue);
         while (sStringColonSplitter.hasNext()) {
-            final String name = sStringColonSplitter.next();
-            if (TextUtils.isEmpty(name) || (componentName.flattenToString()).equals(name)) {
+            final String id = sStringColonSplitter.next();
+            if (TextUtils.isEmpty(id) || componentId.equals(id)) {
                 continue;
             }
-            joiner.add(name);
+            joiner.add(id);
         }
 
         Settings.Secure.putString(context.getContentResolver(), targetsKey, joiner.toString());
     }
 
     /**
+     * Returns if component name existed in one of {@code shortcutTypes} string in Settings.
+     *
+     * @param context The current context.
+     * @param shortcutTypes A combination of {@link UserShortcutType}.
+     * @param componentId The component name that need to be checked existed in Settings.
+     * @return {@code true} if componentName existed in Settings.
+     */
+    private boolean hasValuesInSettings(Context context, int shortcutTypes,
+            @NonNull String componentId) {
+        boolean exist = false;
+        if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
+            exist = hasValueInSettings(context, UserShortcutType.SOFTWARE, componentId);
+        }
+        if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) {
+            exist |= hasValueInSettings(context, UserShortcutType.HARDWARE, componentId);
+        }
+        return exist;
+    }
+
+
+    /**
      * Returns if component name existed in Settings.
      *
      * @param context The current context.
      * @param shortcutType The preferred shortcut type user selected.
-     * @param componentName The component name that need to be checked existed in Settings.
+     * @param componentId The component id that need to be checked existed in Settings.
      * @return {@code true} if componentName existed in Settings.
      */
     private boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType,
-            @NonNull ComponentName componentName) {
+            @NonNull String componentId) {
         final String targetKey = convertToKey(shortcutType);
         final String targetString = Settings.Secure.getString(context.getContentResolver(),
                 targetKey);
@@ -831,8 +838,8 @@
 
         sStringColonSplitter.setString(targetString);
         while (sStringColonSplitter.hasNext()) {
-            final String name = sStringColonSplitter.next();
-            if ((componentName.flattenToString()).equals(name)) {
+            final String id = sStringColonSplitter.next();
+            if (componentId.equals(id)) {
                 return true;
             }
         }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b6b548c..9532fae 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -71,6 +71,7 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Parcelable;
+import android.os.PatternMatcher;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -1650,10 +1651,28 @@
         try {
             final Intent intent = getTargetIntent();
             String dataString = intent.getDataString();
-            if (TextUtils.isEmpty(dataString)) {
-                dataString = intent.getType();
+            if (!TextUtils.isEmpty(dataString)) {
+                return new IntentFilter(intent.getAction(), dataString);
             }
-            return new IntentFilter(intent.getAction(), dataString);
+            IntentFilter intentFilter = new IntentFilter(intent.getAction(), intent.getType());
+            List<Uri> contentUris = new ArrayList<>();
+            if (Intent.ACTION_SEND.equals(intent.getAction())) {
+                Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
+                if (uri != null) {
+                    contentUris.add(uri);
+                }
+            } else {
+                List<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+                if (uris != null) {
+                    contentUris.addAll(uris);
+                }
+            }
+            for (Uri uri : contentUris) {
+                intentFilter.addDataScheme(uri.getScheme());
+                intentFilter.addDataAuthority(uri.getAuthority(), null);
+                intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL);
+            }
+            return intentFilter;
         } catch (Exception e) {
             Log.e(TAG, "failed to get target intent filter " + e);
             return null;
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 179828c..13d0c5c 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -35,6 +35,7 @@
 import com.android.server.NetworkManagementSocketTagger;
 
 import dalvik.system.RuntimeHooks;
+import dalvik.system.ThreadPrioritySetter;
 import dalvik.system.VMRuntime;
 
 import libcore.content.type.MimeMap;
@@ -204,6 +205,7 @@
      */
     public static void preForkInit() {
         if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
+        RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter());
         RuntimeInit.enableDdms();
         // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
         // MimeMap.setDefault(DefaultMimeMapFactory.create());
@@ -216,6 +218,35 @@
         MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
     }
 
+    private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter {
+        // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc
+        private static final int[] NICE_VALUES = {
+            Process.THREAD_PRIORITY_LOWEST,  // 1 (MIN_PRIORITY)
+            Process.THREAD_PRIORITY_BACKGROUND + 6,
+            Process.THREAD_PRIORITY_BACKGROUND + 3,
+            Process.THREAD_PRIORITY_BACKGROUND,
+            Process.THREAD_PRIORITY_DEFAULT,  // 5 (NORM_PRIORITY)
+            Process.THREAD_PRIORITY_DEFAULT - 2,
+            Process.THREAD_PRIORITY_DEFAULT - 4,
+            Process.THREAD_PRIORITY_URGENT_DISPLAY + 3,
+            Process.THREAD_PRIORITY_URGENT_DISPLAY + 2,
+            Process.THREAD_PRIORITY_URGENT_DISPLAY  // 10 (MAX_PRIORITY)
+        };
+
+        @Override
+        public void setPriority(int nativeTid, int priority) {
+            // Check NICE_VALUES[] length first.
+            if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) {
+                throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length);
+            }
+            // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10).
+            if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
+                throw new IllegalArgumentException("Priority out of range: " + priority);
+            }
+            Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]);
+        }
+    }
+
     @UnsupportedAppUsage
     protected static final void commonInit() {
         if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index f0a346a..e2985566 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -35,6 +35,7 @@
 import android.system.Os;
 import android.util.Log;
 
+import dalvik.annotation.optimization.FastNative;
 import dalvik.system.ZygoteHooks;
 
 import libcore.io.IoUtils;
@@ -1018,4 +1019,19 @@
             command.append(" '").append(arg.replace("'", "'\\''")).append("'");
         }
     }
+
+    /**
+     * Parse the given unsolicited zygote message as type SIGCHLD,
+     * extract the payload information into the given output buffer.
+     *
+     * @param in The unsolicited zygote message to be parsed
+     * @param length The number of bytes in the message
+     * @param out The output buffer where the payload information will be placed
+     * @return Number of elements being place into output buffer, or -1 if
+     *         either the message is malformed or not the type as expected here.
+     *
+     * @hide
+     */
+    @FastNative
+    public static native int nativeParseSigChld(byte[] in, int length, int[] out);
 }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 0170978..a6637a2 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1240,9 +1240,6 @@
         }
         updateBackgroundDrawable();
 
-        if (insets != null) {
-            insets = insets.consumeStableInsets();
-        }
         return insets;
     }
 
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 88a9cb0..4abd397 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -27,8 +27,8 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 
 import android.annotation.NonNull;
@@ -2466,7 +2466,7 @@
         if (a.hasValue(R.styleable.Window_windowLayoutInDisplayCutoutMode)) {
             int mode = a.getInt(R.styleable.Window_windowLayoutInDisplayCutoutMode, -1);
             if (mode < LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
-                    || mode > LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
+                    || mode > LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
                 throw new UnsupportedOperationException("Unknown windowLayoutInDisplayCutoutMode: "
                         + a.getString(R.styleable.Window_windowLayoutInDisplayCutoutMode));
             }
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 984f93c..5937283 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -457,15 +457,6 @@
             sk_ref_sp(bitmap->info().colorSpace())));
 }
 
-// These must match the int values in Bitmap.java
-enum JavaEncodeFormat {
-    kJPEG_JavaEncodeFormat = 0,
-    kPNG_JavaEncodeFormat = 1,
-    kWEBP_JavaEncodeFormat = 2,
-    kWEBP_LOSSY_JavaEncodeFormat = 3,
-    kWEBP_LOSSLESS_JavaEncodeFormat = 4,
-};
-
 static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle,
                                 jint format, jint quality,
                                 jobject jstream, jbyteArray jstorage) {
@@ -479,51 +470,9 @@
         return JNI_FALSE;
     }
 
-    SkBitmap skbitmap;
-    bitmap->getSkBitmap(&skbitmap);
-    if (skbitmap.colorType() == kRGBA_F16_SkColorType) {
-        // Convert to P3 before encoding. This matches SkAndroidCodec::computeOutputColorSpace
-        // for wide gamuts.
-        auto cs = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
-        auto info = skbitmap.info().makeColorType(kRGBA_8888_SkColorType)
-                                   .makeColorSpace(std::move(cs));
-        SkBitmap p3;
-        if (!p3.tryAllocPixels(info)) {
-            return JNI_FALSE;
-        }
-
-        SkPixmap pm;
-        SkAssertResult(p3.peekPixels(&pm));  // should always work if tryAllocPixels() did.
-        if (!skbitmap.readPixels(pm)) {
-            return JNI_FALSE;
-        }
-        skbitmap = p3;
-    }
-    SkEncodedImageFormat fm;
-    switch (format) {
-        case kJPEG_JavaEncodeFormat:
-            fm = SkEncodedImageFormat::kJPEG;
-            break;
-        case kPNG_JavaEncodeFormat:
-            fm = SkEncodedImageFormat::kPNG;
-            break;
-        case kWEBP_JavaEncodeFormat:
-            fm = SkEncodedImageFormat::kWEBP;
-            break;
-        case kWEBP_LOSSY_JavaEncodeFormat:
-        case kWEBP_LOSSLESS_JavaEncodeFormat: {
-            SkWebpEncoder::Options options;
-            options.fQuality = quality;
-            options.fCompression = format == kWEBP_LOSSY_JavaEncodeFormat ?
-                    SkWebpEncoder::Compression::kLossy : SkWebpEncoder::Compression::kLossless;
-            return SkWebpEncoder::Encode(strm.get(), skbitmap.pixmap(), options) ?
-                    JNI_TRUE : JNI_FALSE;
-        }
-        default:
-            return JNI_FALSE;
-    }
-
-    return SkEncodeImage(strm.get(), skbitmap, fm, quality) ? JNI_TRUE : JNI_FALSE;
+    auto fm = static_cast<Bitmap::JavaCompressFormat>(format);
+    auto result = bitmap->bitmap().compress(fm, quality, strm.get());
+    return result == Bitmap::CompressResult::Success ? JNI_TRUE : JNI_FALSE;
 }
 
 static inline void bitmapErase(SkBitmap bitmap, const SkColor4f& color,
diff --git a/core/jni/android/graphics/ImageDecoder.cpp b/core/jni/android/graphics/ImageDecoder.cpp
index a900286..e17e057 100644
--- a/core/jni/android/graphics/ImageDecoder.cpp
+++ b/core/jni/android/graphics/ImageDecoder.cpp
@@ -241,7 +241,7 @@
         doThrowISE(env, "Could not scale to target size!");
         return nullptr;
     }
-    if (requireUnpremul && !decoder->setOutAlphaType(kUnpremul_SkAlphaType)) {
+    if (requireUnpremul && !decoder->setUnpremultipliedRequired(true)) {
         doThrowISE(env, "Cannot scale unpremultiplied pixels!");
         return nullptr;
     }
@@ -301,11 +301,15 @@
         }
     }
 
-    SkBitmap bm;
     SkImageInfo bitmapInfo = decoder->getOutputInfo();
+    if (decoder->opaque()) {
+        bitmapInfo = bitmapInfo.makeAlphaType(kOpaque_SkAlphaType);
+    }
     if (asAlphaMask && colorType == kGray_8_SkColorType) {
         bitmapInfo = bitmapInfo.makeColorType(kAlpha_8_SkColorType);
     }
+
+    SkBitmap bm;
     if (!bm.setInfo(bitmapInfo)) {
         doThrowIOE(env, "Failed to setInfo properly");
         return nullptr;
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 1a9e8d0..2aca317 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -23,10 +23,10 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include <gui/Surface.h>
-#include <gui/surfacetexture/SurfaceTexture.h>
 #include <gui/BufferQueue.h>
-#include <gui/surfacetexture/surface_texture_platform.h>
+#include <gui/Surface.h>
+#include <surfacetexture/SurfaceTexture.h>
+#include <surfacetexture/surface_texture_platform.h>
 
 #include "core_jni_helpers.h"
 
diff --git a/core/jni/android/graphics/apex/android_bitmap.cpp b/core/jni/android/graphics/apex/android_bitmap.cpp
index 6a3c01e..b8e04a7 100644
--- a/core/jni/android/graphics/apex/android_bitmap.cpp
+++ b/core/jni/android/graphics/apex/android_bitmap.cpp
@@ -23,6 +23,7 @@
 
 #include <GraphicsJNI.h>
 #include <hwui/Bitmap.h>
+#include <utils/Color.h>
 
 using namespace android;
 
@@ -122,6 +123,7 @@
     return getInfo(bitmap->info(), bitmap->rowBytes());
 }
 
+namespace {
 static bool nearlyEqual(float a, float b) {
     // By trial and error, this is close enough to match for the ADataSpaces we
     // compare for.
@@ -156,6 +158,7 @@
         {0.226676, 0.710327, 0.0629966},
         {0.000800549, 0.0432385, 0.78275},
 }};
+} // anonymous namespace
 
 ADataSpace ABitmap_getDataSpace(ABitmap* bitmapHandle) {
     Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
@@ -243,3 +246,135 @@
     }
     return bitmap->notifyPixelsChanged();
 }
+
+namespace {
+SkAlphaType getAlphaType(const AndroidBitmapInfo* info) {
+    switch (info->flags & ANDROID_BITMAP_FLAGS_ALPHA_MASK) {
+        case ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE:
+            return kOpaque_SkAlphaType;
+        case ANDROID_BITMAP_FLAGS_ALPHA_PREMUL:
+            return kPremul_SkAlphaType;
+        case ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL:
+            return kUnpremul_SkAlphaType;
+        default:
+            return kUnknown_SkAlphaType;
+    }
+}
+
+class CompressWriter : public SkWStream {
+public:
+    CompressWriter(void* userContext, AndroidBitmap_compress_write_fn fn)
+          : mUserContext(userContext), mFn(fn), mBytesWritten(0) {}
+
+    bool write(const void* buffer, size_t size) override {
+        if (mFn(mUserContext, buffer, size)) {
+            mBytesWritten += size;
+            return true;
+        }
+        return false;
+    }
+
+    size_t bytesWritten() const override { return mBytesWritten; }
+
+private:
+    void* mUserContext;
+    AndroidBitmap_compress_write_fn mFn;
+    size_t mBytesWritten;
+};
+
+} // anonymous namespace
+
+int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const void* pixels,
+                     AndroidBitmapCompressFormat inFormat, int32_t quality, void* userContext,
+                     AndroidBitmap_compress_write_fn fn) {
+    Bitmap::JavaCompressFormat format;
+    switch (inFormat) {
+        case ANDROID_BITMAP_COMPRESS_FORMAT_JPEG:
+            format = Bitmap::JavaCompressFormat::Jpeg;
+            break;
+        case ANDROID_BITMAP_COMPRESS_FORMAT_PNG:
+            format = Bitmap::JavaCompressFormat::Png;
+            break;
+        case ANDROID_BITMAP_COMPRESS_FORMAT_WEBP_LOSSY:
+            format = Bitmap::JavaCompressFormat::WebpLossy;
+            break;
+        case ANDROID_BITMAP_COMPRESS_FORMAT_WEBP_LOSSLESS:
+            format = Bitmap::JavaCompressFormat::WebpLossless;
+            break;
+        default:
+            // kWEBP_JavaEncodeFormat is a valid parameter for Bitmap::compress,
+            // for the deprecated Bitmap.CompressFormat.WEBP, but it should not
+            // be provided via the NDK. Other integers are likewise invalid.
+            return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+    }
+
+    SkColorType colorType;
+    switch (info->format) {
+        case ANDROID_BITMAP_FORMAT_RGBA_8888:
+            colorType = kN32_SkColorType;
+            break;
+        case ANDROID_BITMAP_FORMAT_RGB_565:
+            colorType = kRGB_565_SkColorType;
+            break;
+        case ANDROID_BITMAP_FORMAT_A_8:
+            // FIXME b/146637821: Should this encode as grayscale? We should
+            // make the same decision as for encoding an android.graphics.Bitmap.
+            // Note that encoding kAlpha_8 as WebP or JPEG will fail. Encoding
+            // it to PNG encodes as GRAY+ALPHA with a secret handshake that we
+            // only care about the alpha. I'm not sure whether Android decoding
+            // APIs respect that handshake.
+            colorType = kAlpha_8_SkColorType;
+            break;
+        case ANDROID_BITMAP_FORMAT_RGBA_F16:
+            colorType = kRGBA_F16_SkColorType;
+            break;
+        default:
+            return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+    }
+
+    auto alphaType = getAlphaType(info);
+    if (alphaType == kUnknown_SkAlphaType) {
+        return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+    }
+
+    sk_sp<SkColorSpace> cs;
+    if (info->format == ANDROID_BITMAP_FORMAT_A_8) {
+        // FIXME: A Java Bitmap with ALPHA_8 never has a ColorSpace. So should
+        // we force that here (as I'm doing now) or should we treat anything
+        // besides ADATASPACE_UNKNOWN as an error?
+        cs = nullptr;
+    } else {
+        cs = uirenderer::DataSpaceToColorSpace((android_dataspace) dataSpace);
+        // DataSpaceToColorSpace treats UNKNOWN as SRGB, but compress forces the
+        // client to specify SRGB if that is what they want.
+        if (!cs || dataSpace == ADATASPACE_UNKNOWN) {
+            return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+        }
+    }
+
+    {
+        size_t size;
+        if (!Bitmap::computeAllocationSize(info->stride, info->height, &size)) {
+            return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+        }
+    }
+
+    auto imageInfo =
+            SkImageInfo::Make(info->width, info->height, colorType, alphaType, std::move(cs));
+    SkBitmap bitmap;
+    // We are not going to modify the pixels, but installPixels expects them to
+    // not be const, since for all it knows we might want to draw to the SkBitmap.
+    if (!bitmap.installPixels(imageInfo, const_cast<void*>(pixels), info->stride)) {
+        return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+    }
+
+    CompressWriter stream(userContext, fn);
+    switch (Bitmap::compress(bitmap, format, quality, &stream)) {
+        case Bitmap::CompressResult::Success:
+            return ANDROID_BITMAP_RESULT_SUCCESS;
+        case Bitmap::CompressResult::AllocationFailed:
+            return ANDROID_BITMAP_RESULT_ALLOCATION_FAILED;
+        case Bitmap::CompressResult::Error:
+            return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
+    }
+}
diff --git a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
index 32b8a45..683851d 100644
--- a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
+++ b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
@@ -58,6 +58,11 @@
 AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj);
 jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
 
+// NDK access
+int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const void* pixels,
+                     AndroidBitmapCompressFormat format, int32_t quality, void* userContext,
+                     AndroidBitmap_compress_write_fn);
+
 __END_DECLS
 
 #ifdef	__cplusplus
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index d9ed07e..c80f1dc 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -59,14 +59,12 @@
 static const int BUSY_TIMEOUT_MS = 2500;
 
 static struct {
-    jfieldID name;
-    jfieldID numArgs;
-    jmethodID dispatchCallback;
-} gSQLiteCustomFunctionClassInfo;
+    jmethodID apply;
+} gUnaryOperator;
 
 static struct {
-    jclass clazz;
-} gStringClassInfo;
+    jmethodID apply;
+} gBinaryOperator;
 
 struct SQLiteConnection {
     // Open flags.
@@ -203,74 +201,146 @@
     }
 }
 
-// Called each time a custom function is evaluated.
-static void sqliteCustomFunctionCallback(sqlite3_context *context,
+static void sqliteCustomScalarFunctionCallback(sqlite3_context *context,
         int argc, sqlite3_value **argv) {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
-
-    // Get the callback function object.
-    // Create a new local reference to it in case the callback tries to do something
-    // dumb like unregister the function (thereby destroying the global ref) while it is running.
     jobject functionObjGlobal = reinterpret_cast<jobject>(sqlite3_user_data(context));
-    jobject functionObj = env->NewLocalRef(functionObjGlobal);
-
-    jobjectArray argsArray = env->NewObjectArray(argc, gStringClassInfo.clazz, NULL);
-    if (argsArray) {
-        for (int i = 0; i < argc; i++) {
-            const jchar* arg = static_cast<const jchar*>(sqlite3_value_text16(argv[i]));
-            if (!arg) {
-                ALOGW("NULL argument in custom_function_callback.  This should not happen.");
-            } else {
-                size_t argLen = sqlite3_value_bytes16(argv[i]) / sizeof(jchar);
-                jstring argStr = env->NewString(arg, argLen);
-                if (!argStr) {
-                    goto error; // out of memory error
-                }
-                env->SetObjectArrayElement(argsArray, i, argStr);
-                env->DeleteLocalRef(argStr);
-            }
-        }
-
-        // TODO: Support functions that return values.
-        env->CallVoidMethod(functionObj,
-                gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray);
-
-error:
-        env->DeleteLocalRef(argsArray);
-    }
-
-    env->DeleteLocalRef(functionObj);
+    ScopedLocalRef<jobject> functionObj(env, env->NewLocalRef(functionObjGlobal));
+    ScopedLocalRef<jstring> argString(env,
+            env->NewStringUTF(reinterpret_cast<const char*>(sqlite3_value_text(argv[0]))));
+    ScopedLocalRef<jstring> resString(env,
+            (jstring) env->CallObjectMethod(functionObj.get(), gUnaryOperator.apply, argString.get()));
 
     if (env->ExceptionCheck()) {
-        ALOGE("An exception was thrown by custom SQLite function.");
-        LOGE_EX(env);
+        ALOGE("Exception thrown by custom scalar function");
+        sqlite3_result_error(context, "Exception thrown by custom scalar function", -1);
+        env->ExceptionDescribe();
         env->ExceptionClear();
+        return;
+    }
+
+    if (resString.get() == nullptr) {
+        sqlite3_result_null(context);
+    } else {
+        ScopedUtfChars res(env, resString.get());
+        sqlite3_result_text(context, res.c_str(), -1, SQLITE_TRANSIENT);
     }
 }
 
-// Called when a custom function is destroyed.
-static void sqliteCustomFunctionDestructor(void* data) {
+static void sqliteCustomScalarFunctionDestructor(void* data) {
     jobject functionObjGlobal = reinterpret_cast<jobject>(data);
 
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     env->DeleteGlobalRef(functionObjGlobal);
 }
 
-static void nativeRegisterCustomFunction(JNIEnv* env, jclass clazz, jlong connectionPtr,
-        jobject functionObj) {
+static void nativeRegisterCustomScalarFunction(JNIEnv* env, jclass clazz, jlong connectionPtr,
+        jstring functionName, jobject functionObj) {
     SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
 
-    jstring nameStr = jstring(env->GetObjectField(
-            functionObj, gSQLiteCustomFunctionClassInfo.name));
-    jint numArgs = env->GetIntField(functionObj, gSQLiteCustomFunctionClassInfo.numArgs);
+    jobject functionObjGlobal = env->NewGlobalRef(functionObj);
+    ScopedUtfChars functionNameChars(env, functionName);
+    int err = sqlite3_create_function_v2(connection->db,
+            functionNameChars.c_str(), 1, SQLITE_UTF8,
+            reinterpret_cast<void*>(functionObjGlobal),
+            &sqliteCustomScalarFunctionCallback,
+            nullptr,
+            nullptr,
+            &sqliteCustomScalarFunctionDestructor);
+
+    if (err != SQLITE_OK) {
+        ALOGE("sqlite3_create_function returned %d", err);
+        env->DeleteGlobalRef(functionObjGlobal);
+        throw_sqlite3_exception(env, connection->db);
+        return;
+    }
+}
+
+static void sqliteCustomAggregateFunctionStep(sqlite3_context *context,
+        int argc, sqlite3_value **argv) {
+    char** agg = reinterpret_cast<char**>(
+            sqlite3_aggregate_context(context, sizeof(const char**)));
+    if (agg == nullptr) {
+        return;
+    } else if (*agg == nullptr) {
+        // During our first call the best we can do is allocate our result
+        // holder and populate it with our first value; we'll reduce it
+        // against any additional values in future calls
+        const char* res = reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
+        if (res == nullptr) {
+            *agg = nullptr;
+        } else {
+            *agg = strdup(res);
+        }
+        return;
+    }
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject functionObjGlobal = reinterpret_cast<jobject>(sqlite3_user_data(context));
+    ScopedLocalRef<jobject> functionObj(env, env->NewLocalRef(functionObjGlobal));
+    ScopedLocalRef<jstring> arg0String(env,
+            env->NewStringUTF(reinterpret_cast<const char*>(*agg)));
+    ScopedLocalRef<jstring> arg1String(env,
+            env->NewStringUTF(reinterpret_cast<const char*>(sqlite3_value_text(argv[0]))));
+    ScopedLocalRef<jstring> resString(env,
+            (jstring) env->CallObjectMethod(functionObj.get(), gBinaryOperator.apply,
+                    arg0String.get(), arg1String.get()));
+
+    if (env->ExceptionCheck()) {
+        ALOGE("Exception thrown by custom aggregate function");
+        sqlite3_result_error(context, "Exception thrown by custom aggregate function", -1);
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+        return;
+    }
+
+    // One way or another, we have a new value to collect, and we need to
+    // free our previous value
+    if (*agg != nullptr) {
+        free(*agg);
+    }
+    if (resString.get() == nullptr) {
+        *agg = nullptr;
+    } else {
+        ScopedUtfChars res(env, resString.get());
+        *agg = strdup(res.c_str());
+    }
+}
+
+static void sqliteCustomAggregateFunctionFinal(sqlite3_context *context) {
+    // We pass zero size here to avoid allocating for empty sets
+    char** agg = reinterpret_cast<char**>(
+            sqlite3_aggregate_context(context, 0));
+    if (agg == nullptr) {
+        return;
+    } else if (*agg == nullptr) {
+        sqlite3_result_null(context);
+    } else {
+        sqlite3_result_text(context, *agg, -1, SQLITE_TRANSIENT);
+        free(*agg);
+    }
+}
+
+static void sqliteCustomAggregateFunctionDestructor(void* data) {
+    jobject functionObjGlobal = reinterpret_cast<jobject>(data);
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteGlobalRef(functionObjGlobal);
+}
+
+static void nativeRegisterCustomAggregateFunction(JNIEnv* env, jclass clazz, jlong connectionPtr,
+        jstring functionName, jobject functionObj) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
 
     jobject functionObjGlobal = env->NewGlobalRef(functionObj);
-
-    const char* name = env->GetStringUTFChars(nameStr, NULL);
-    int err = sqlite3_create_function_v2(connection->db, name, numArgs, SQLITE_UTF16,
+    ScopedUtfChars functionNameChars(env, functionName);
+    int err = sqlite3_create_function_v2(connection->db,
+            functionNameChars.c_str(), 1, SQLITE_UTF8,
             reinterpret_cast<void*>(functionObjGlobal),
-            &sqliteCustomFunctionCallback, NULL, NULL, &sqliteCustomFunctionDestructor);
-    env->ReleaseStringUTFChars(nameStr, name);
+            nullptr,
+            &sqliteCustomAggregateFunctionStep,
+            &sqliteCustomAggregateFunctionFinal,
+            &sqliteCustomAggregateFunctionDestructor);
 
     if (err != SQLITE_OK) {
         ALOGE("sqlite3_create_function returned %d", err);
@@ -812,8 +882,10 @@
             (void*)nativeOpen },
     { "nativeClose", "(J)V",
             (void*)nativeClose },
-    { "nativeRegisterCustomFunction", "(JLandroid/database/sqlite/SQLiteCustomFunction;)V",
-            (void*)nativeRegisterCustomFunction },
+    { "nativeRegisterCustomScalarFunction", "(JLjava/lang/String;Ljava/util/function/UnaryOperator;)V",
+            (void*)nativeRegisterCustomScalarFunction },
+    { "nativeRegisterCustomAggregateFunction", "(JLjava/lang/String;Ljava/util/function/BinaryOperator;)V",
+            (void*)nativeRegisterCustomAggregateFunction },
     { "nativeRegisterLocalizedCollators", "(JLjava/lang/String;)V",
             (void*)nativeRegisterLocalizedCollators },
     { "nativePrepareStatement", "(JLjava/lang/String;)J",
@@ -864,15 +936,13 @@
 
 int register_android_database_SQLiteConnection(JNIEnv *env)
 {
-    jclass clazz = FindClassOrDie(env, "android/database/sqlite/SQLiteCustomFunction");
+    jclass unaryClazz = FindClassOrDie(env, "java/util/function/UnaryOperator");
+    gUnaryOperator.apply = GetMethodIDOrDie(env, unaryClazz,
+            "apply", "(Ljava/lang/Object;)Ljava/lang/Object;");
 
-    gSQLiteCustomFunctionClassInfo.name = GetFieldIDOrDie(env, clazz, "name", "Ljava/lang/String;");
-    gSQLiteCustomFunctionClassInfo.numArgs = GetFieldIDOrDie(env, clazz, "numArgs", "I");
-    gSQLiteCustomFunctionClassInfo.dispatchCallback = GetMethodIDOrDie(env, clazz,
-            "dispatchCallback", "([Ljava/lang/String;)V");
-
-    clazz = FindClassOrDie(env, "java/lang/String");
-    gStringClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
+    jclass binaryClazz = FindClassOrDie(env, "java/util/function/BinaryOperator");
+    gBinaryOperator.apply = GetMethodIDOrDie(env, binaryClazz,
+            "apply", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
 
     return RegisterMethodsOrDie(env, "android/database/sqlite/SQLiteConnection", sMethods,
                                 NELEM(sMethods));
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index f2a51ad..8cf1d2c 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -27,14 +27,14 @@
 #include "android_runtime/android_view_Surface.h"
 #include "android_runtime/android_graphics_SurfaceTexture.h"
 
-#include <gui/Surface.h>
-#include <gui/surfacetexture/SurfaceTexture.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/IProducerListener.h>
-#include <ui/GraphicBuffer.h>
-#include <system/window.h>
+#include <gui/Surface.h>
 #include <hardware/camera3.h>
+#include <surfacetexture/SurfaceTexture.h>
 #include <system/camera_metadata.h>
+#include <system/window.h>
+#include <ui/GraphicBuffer.h>
 
 #include <stdint.h>
 #include <inttypes.h>
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index c979133..041019e 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -102,6 +102,47 @@
     }
 };
 
+class TunerConfigurationHelper {
+    JNIEnv *const mEnv;
+    jobject const mTunerConfiguration;
+
+    struct Ids {
+        Ids(JNIEnv *env)
+              : mClass(FindClassOrDie(env, "android/media/AudioTrack$TunerConfiguration")),
+                mContentId(GetFieldIDOrDie(env, mClass, "mContentId", "I")),
+                mSyncId(GetFieldIDOrDie(env, mClass, "mSyncId", "I")) {}
+        const jclass mClass;
+        const jfieldID mContentId;
+        const jfieldID mSyncId;
+    };
+
+    static const Ids &getIds(JNIEnv *env) {
+        // Meyer's singleton, initializes first time control passes through
+        // declaration in a block and is thread-safe per ISO/IEC 14882:2011 6.7.4.
+        static Ids ids(env);
+        return ids;
+    }
+
+public:
+    TunerConfigurationHelper(JNIEnv *env, jobject tunerConfiguration)
+          : mEnv(env), mTunerConfiguration(tunerConfiguration) {}
+
+    int32_t getContentId() const {
+        if (mEnv == nullptr || mTunerConfiguration == nullptr) return 0;
+        const Ids &ids = getIds(mEnv);
+        return (int32_t)mEnv->GetIntField(mTunerConfiguration, ids.mContentId);
+    }
+
+    int32_t getSyncId() const {
+        if (mEnv == nullptr || mTunerConfiguration == nullptr) return 0;
+        const Ids &ids = getIds(mEnv);
+        return (int32_t)mEnv->GetIntField(mTunerConfiguration, ids.mSyncId);
+    }
+
+    // optional check to confirm class and field ids can be found.
+    static void initCheckOrDie(JNIEnv *env) { (void)getIds(env); }
+};
+
 static Mutex sLock;
 static SortedVector <audiotrack_callback_cookie *> sAudioTrackCallBackCookies;
 
@@ -213,24 +254,36 @@
 }
 
 // ----------------------------------------------------------------------------
-static jint
-android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this, jobject jaa,
-        jintArray jSampleRate, jint channelPositionMask, jint channelIndexMask,
-        jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession,
-        jlong nativeAudioTrack, jboolean offload) {
-
+static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+                                           jobject jaa, jintArray jSampleRate,
+                                           jint channelPositionMask, jint channelIndexMask,
+                                           jint audioFormat, jint buffSizeInBytes, jint memoryMode,
+                                           jintArray jSession, jlong nativeAudioTrack,
+                                           jboolean offload, jint encapsulationMode,
+                                           jobject tunerConfiguration) {
     ALOGV("sampleRates=%p, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d,"
-        " nativeAudioTrack=0x%" PRIX64 ", offload=%d",
-        jSampleRate, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes,
-        nativeAudioTrack, offload);
-
-    sp<AudioTrack> lpTrack = 0;
+          " nativeAudioTrack=0x%" PRIX64 ", offload=%d encapsulationMode=%d tuner=%p",
+          jSampleRate, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes,
+          nativeAudioTrack, offload, encapsulationMode, tunerConfiguration);
 
     if (jSession == NULL) {
         ALOGE("Error creating AudioTrack: invalid session ID pointer");
         return (jint) AUDIO_JAVA_ERROR;
     }
 
+    // TODO: replace when we land matching AudioTrack::set() in frameworks/av in r or r-tv-dev.
+    if (tunerConfiguration != nullptr) {
+        const TunerConfigurationHelper tunerHelper(env, tunerConfiguration);
+        ALOGE("Error creating AudioTrack: unsupported tuner contentId:%d syncId:%d",
+              tunerHelper.getContentId(), tunerHelper.getSyncId());
+        return (jint)AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
+    }
+    // TODO: replace when we land matching AudioTrack::set() in frameworks/av in r or r-tv-dev.
+    if (encapsulationMode != 0 /* ENCAPSULATION_MODE_NONE */) {
+        ALOGE("Error creating AudioTrack: unsupported encapsulationMode %d", encapsulationMode);
+        return (jint)AUDIOTRACK_ERROR_SETUP_NATIVEINITFAILED;
+    }
+
     jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
     if (nSession == NULL) {
         ALOGE("Error creating AudioTrack: Error retrieving session id pointer");
@@ -249,6 +302,7 @@
     }
 
     // if we pass in an existing *Native* AudioTrack, we don't need to create/initialize one.
+    sp<AudioTrack> lpTrack;
     if (nativeAudioTrack == 0) {
         if (jaa == 0) {
             ALOGE("Error creating AudioTrack: invalid audio attributes");
@@ -1304,82 +1358,75 @@
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
-    // name,              signature,     funcPtr
-    {"native_is_direct_output_supported",
-                             "(IIIIIII)Z",
-                                         (void *)android_media_AudioTrack_is_direct_output_supported},
-    {"native_start",         "()V",      (void *)android_media_AudioTrack_start},
-    {"native_stop",          "()V",      (void *)android_media_AudioTrack_stop},
-    {"native_pause",         "()V",      (void *)android_media_AudioTrack_pause},
-    {"native_flush",         "()V",      (void *)android_media_AudioTrack_flush},
-    {"native_setup",     "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZ)I",
-                                         (void *)android_media_AudioTrack_setup},
-    {"native_finalize",      "()V",      (void *)android_media_AudioTrack_finalize},
-    {"native_release",       "()V",      (void *)android_media_AudioTrack_release},
-    {"native_write_byte",    "([BIIIZ)I",(void *)android_media_AudioTrack_writeArray<jbyteArray>},
-    {"native_write_native_bytes",
-                             "(Ljava/nio/ByteBuffer;IIIZ)I",
-                                         (void *)android_media_AudioTrack_write_native_bytes},
-    {"native_write_short",   "([SIIIZ)I",(void *)android_media_AudioTrack_writeArray<jshortArray>},
-    {"native_write_float",   "([FIIIZ)I",(void *)android_media_AudioTrack_writeArray<jfloatArray>},
-    {"native_setVolume",     "(FF)V",    (void *)android_media_AudioTrack_set_volume},
-    {"native_get_buffer_size_frames",
-                             "()I",      (void *)android_media_AudioTrack_get_buffer_size_frames},
-    {"native_set_buffer_size_frames",
-                             "(I)I",     (void *)android_media_AudioTrack_set_buffer_size_frames},
-    {"native_get_buffer_capacity_frames",
-                             "()I",      (void *)android_media_AudioTrack_get_buffer_capacity_frames},
-    {"native_set_playback_rate",
-                             "(I)I",     (void *)android_media_AudioTrack_set_playback_rate},
-    {"native_get_playback_rate",
-                             "()I",      (void *)android_media_AudioTrack_get_playback_rate},
-    {"native_set_playback_params",
-                             "(Landroid/media/PlaybackParams;)V",
-                                         (void *)android_media_AudioTrack_set_playback_params},
-    {"native_get_playback_params",
-                             "()Landroid/media/PlaybackParams;",
-                                         (void *)android_media_AudioTrack_get_playback_params},
-    {"native_set_marker_pos","(I)I",     (void *)android_media_AudioTrack_set_marker_pos},
-    {"native_get_marker_pos","()I",      (void *)android_media_AudioTrack_get_marker_pos},
-    {"native_set_pos_update_period",
-                             "(I)I",     (void *)android_media_AudioTrack_set_pos_update_period},
-    {"native_get_pos_update_period",
-                             "()I",      (void *)android_media_AudioTrack_get_pos_update_period},
-    {"native_set_position",  "(I)I",     (void *)android_media_AudioTrack_set_position},
-    {"native_get_position",  "()I",      (void *)android_media_AudioTrack_get_position},
-    {"native_get_latency",   "()I",      (void *)android_media_AudioTrack_get_latency},
-    {"native_get_underrun_count", "()I",      (void *)android_media_AudioTrack_get_underrun_count},
-    {"native_get_flags",     "()I",      (void *)android_media_AudioTrack_get_flags},
-    {"native_get_timestamp", "([J)I",    (void *)android_media_AudioTrack_get_timestamp},
-    {"native_getMetrics",    "()Landroid/os/PersistableBundle;",
-                                         (void *)android_media_AudioTrack_native_getMetrics},
-    {"native_set_loop",      "(III)I",   (void *)android_media_AudioTrack_set_loop},
-    {"native_reload_static", "()I",      (void *)android_media_AudioTrack_reload},
-    {"native_get_output_sample_rate",
-                             "(I)I",      (void *)android_media_AudioTrack_get_output_sample_rate},
-    {"native_get_min_buff_size",
-                             "(III)I",   (void *)android_media_AudioTrack_get_min_buff_size},
-    {"native_setAuxEffectSendLevel",
-                             "(F)I",     (void *)android_media_AudioTrack_setAuxEffectSendLevel},
-    {"native_attachAuxEffect",
-                             "(I)I",     (void *)android_media_AudioTrack_attachAuxEffect},
-    {"native_setOutputDevice", "(I)Z",
-                             (void *)android_media_AudioTrack_setOutputDevice},
-    {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId},
-    {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback},
-    {"native_disableDeviceCallback", "()V", (void *)android_media_AudioTrack_disableDeviceCallback},
-    {"native_applyVolumeShaper",
-            "(Landroid/media/VolumeShaper$Configuration;Landroid/media/VolumeShaper$Operation;)I",
-                                         (void *)android_media_AudioTrack_apply_volume_shaper},
-    {"native_getVolumeShaperState",
-            "(I)Landroid/media/VolumeShaper$State;",
-                                        (void *)android_media_AudioTrack_get_volume_shaper_state},
-    {"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
-    {"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
-    {"native_set_delay_padding", "(II)V", (void *)android_media_AudioTrack_set_delay_padding},
+        // name,              signature,     funcPtr
+        {"native_is_direct_output_supported", "(IIIIIII)Z",
+         (void *)android_media_AudioTrack_is_direct_output_supported},
+        {"native_start", "()V", (void *)android_media_AudioTrack_start},
+        {"native_stop", "()V", (void *)android_media_AudioTrack_stop},
+        {"native_pause", "()V", (void *)android_media_AudioTrack_pause},
+        {"native_flush", "()V", (void *)android_media_AudioTrack_flush},
+        {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;)I",
+         (void *)android_media_AudioTrack_setup},
+        {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize},
+        {"native_release", "()V", (void *)android_media_AudioTrack_release},
+        {"native_write_byte", "([BIIIZ)I", (void *)android_media_AudioTrack_writeArray<jbyteArray>},
+        {"native_write_native_bytes", "(Ljava/nio/ByteBuffer;IIIZ)I",
+         (void *)android_media_AudioTrack_write_native_bytes},
+        {"native_write_short", "([SIIIZ)I",
+         (void *)android_media_AudioTrack_writeArray<jshortArray>},
+        {"native_write_float", "([FIIIZ)I",
+         (void *)android_media_AudioTrack_writeArray<jfloatArray>},
+        {"native_setVolume", "(FF)V", (void *)android_media_AudioTrack_set_volume},
+        {"native_get_buffer_size_frames", "()I",
+         (void *)android_media_AudioTrack_get_buffer_size_frames},
+        {"native_set_buffer_size_frames", "(I)I",
+         (void *)android_media_AudioTrack_set_buffer_size_frames},
+        {"native_get_buffer_capacity_frames", "()I",
+         (void *)android_media_AudioTrack_get_buffer_capacity_frames},
+        {"native_set_playback_rate", "(I)I", (void *)android_media_AudioTrack_set_playback_rate},
+        {"native_get_playback_rate", "()I", (void *)android_media_AudioTrack_get_playback_rate},
+        {"native_set_playback_params", "(Landroid/media/PlaybackParams;)V",
+         (void *)android_media_AudioTrack_set_playback_params},
+        {"native_get_playback_params", "()Landroid/media/PlaybackParams;",
+         (void *)android_media_AudioTrack_get_playback_params},
+        {"native_set_marker_pos", "(I)I", (void *)android_media_AudioTrack_set_marker_pos},
+        {"native_get_marker_pos", "()I", (void *)android_media_AudioTrack_get_marker_pos},
+        {"native_set_pos_update_period", "(I)I",
+         (void *)android_media_AudioTrack_set_pos_update_period},
+        {"native_get_pos_update_period", "()I",
+         (void *)android_media_AudioTrack_get_pos_update_period},
+        {"native_set_position", "(I)I", (void *)android_media_AudioTrack_set_position},
+        {"native_get_position", "()I", (void *)android_media_AudioTrack_get_position},
+        {"native_get_latency", "()I", (void *)android_media_AudioTrack_get_latency},
+        {"native_get_underrun_count", "()I", (void *)android_media_AudioTrack_get_underrun_count},
+        {"native_get_flags", "()I", (void *)android_media_AudioTrack_get_flags},
+        {"native_get_timestamp", "([J)I", (void *)android_media_AudioTrack_get_timestamp},
+        {"native_getMetrics", "()Landroid/os/PersistableBundle;",
+         (void *)android_media_AudioTrack_native_getMetrics},
+        {"native_set_loop", "(III)I", (void *)android_media_AudioTrack_set_loop},
+        {"native_reload_static", "()I", (void *)android_media_AudioTrack_reload},
+        {"native_get_output_sample_rate", "(I)I",
+         (void *)android_media_AudioTrack_get_output_sample_rate},
+        {"native_get_min_buff_size", "(III)I", (void *)android_media_AudioTrack_get_min_buff_size},
+        {"native_setAuxEffectSendLevel", "(F)I",
+         (void *)android_media_AudioTrack_setAuxEffectSendLevel},
+        {"native_attachAuxEffect", "(I)I", (void *)android_media_AudioTrack_attachAuxEffect},
+        {"native_setOutputDevice", "(I)Z", (void *)android_media_AudioTrack_setOutputDevice},
+        {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId},
+        {"native_enableDeviceCallback", "()V",
+         (void *)android_media_AudioTrack_enableDeviceCallback},
+        {"native_disableDeviceCallback", "()V",
+         (void *)android_media_AudioTrack_disableDeviceCallback},
+        {"native_applyVolumeShaper",
+         "(Landroid/media/VolumeShaper$Configuration;Landroid/media/VolumeShaper$Operation;)I",
+         (void *)android_media_AudioTrack_apply_volume_shaper},
+        {"native_getVolumeShaperState", "(I)Landroid/media/VolumeShaper$State;",
+         (void *)android_media_AudioTrack_get_volume_shaper_state},
+        {"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
+        {"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
+        {"native_set_delay_padding", "(II)V", (void *)android_media_AudioTrack_set_delay_padding},
 };
 
-
 // field names found in android/media/AudioTrack.java
 #define JAVA_POSTEVENT_CALLBACK_NAME                    "postEventFromNative"
 #define JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME            "mNativeTrackInJavaObj"
@@ -1436,6 +1483,10 @@
     gPlaybackParamsFields.init(env);
 
     gVolumeShaperFields.init(env);
+
+    // optional check that the TunerConfiguration class and fields exist.
+    TunerConfigurationHelper::initCheckOrDie(env);
+
     return res;
 }
 
diff --git a/core/jni/android_view_TextureLayer.cpp b/core/jni/android_view_TextureLayer.cpp
index 5491a33..40f6180 100644
--- a/core/jni/android_view_TextureLayer.cpp
+++ b/core/jni/android_view_TextureLayer.cpp
@@ -19,12 +19,9 @@
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
 
+#include <android/surface_texture_jni.h>
 #include "core_jni_helpers.h"
-#include <android_runtime/android_graphics_SurfaceTexture.h>
 
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/surfacetexture/surface_texture_platform.h>
-#include <gui/surfacetexture/SurfaceTexture.h>
 #include <hwui/Paint.h>
 #include <SkMatrix.h>
 #include <DeferredLayerUpdater.h>
@@ -61,10 +58,8 @@
 static void TextureLayer_setSurfaceTexture(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr, jobject surface) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
-    auto consumer = SurfaceTexture_getSurfaceTexture(env, surface);
-    auto producer = SurfaceTexture_getProducer(env, surface);
-    layer->setSurfaceTexture(AutoTextureRelease(
-            ASurfaceTexture_create(consumer, producer)));
+    ASurfaceTexture* surfaceTexture = ASurfaceTexture_fromSurfaceTexture(env, surface);
+    layer->setSurfaceTexture(AutoTextureRelease(surfaceTexture, &ASurfaceTexture_release));
 }
 
 static void TextureLayer_updateSurfaceTexture(JNIEnv* env, jobject clazz,
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 05b573a..2535fcf 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -67,6 +67,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/un.h>
 #include <sys/utsname.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -163,6 +164,12 @@
  */
 static int gUsapPoolEventFD = -1;
 
+/**
+ * The socket file descriptor used to send notifications to the
+ * system_server.
+ */
+static int gSystemServerSocketFd = -1;
+
 static constexpr int DEFAULT_DATA_DIR_PERMISSION = 0751;
 
 /**
@@ -344,6 +351,26 @@
   PROFILE_FROM_SHELL = 1 << 15,
 };
 
+enum UnsolicitedZygoteMessageTypes : uint32_t {
+    UNSOLICITED_ZYGOTE_MESSAGE_TYPE_RESERVED = 0,
+    UNSOLICITED_ZYGOTE_MESSAGE_TYPE_SIGCHLD = 1,
+};
+
+struct UnsolicitedZygoteMessageSigChld {
+    struct {
+        UnsolicitedZygoteMessageTypes type;
+    } header;
+    struct {
+        pid_t pid;
+        uid_t uid;
+        int status;
+    } payload;
+};
+
+// Keep sync with services/core/java/com/android/server/am/ProcessList.java
+static constexpr struct sockaddr_un kSystemServerSockAddr =
+        {.sun_family = AF_LOCAL, .sun_path = "/data/system/unsolzygotesocket"};
+
 // Forward declaration so we don't have to move the signal handler.
 static bool RemoveUsapTableEntry(pid_t usap_pid);
 
@@ -353,74 +380,107 @@
   env->FatalError(oss.str().c_str());
 }
 
+// Create the socket which is going to be used to send unsolicited message
+// to system_server, the socket will be closed post forking a child process.
+// It's expected to be called at each zygote's initialization.
+static void initUnsolSocketToSystemServer() {
+    gSystemServerSocketFd = socket(AF_LOCAL, SOCK_DGRAM | SOCK_NONBLOCK, 0);
+    if (gSystemServerSocketFd >= 0) {
+        ALOGV("Zygote:systemServerSocketFD = %d", gSystemServerSocketFd);
+    } else {
+        ALOGE("Unable to create socket file descriptor to connect to system_server");
+    }
+}
+
+static void sendSigChildStatus(const pid_t pid, const uid_t uid, const int status) {
+    int socketFd = gSystemServerSocketFd;
+    if (socketFd >= 0) {
+        // fill the message buffer
+        struct UnsolicitedZygoteMessageSigChld data =
+                {.header = {.type = UNSOLICITED_ZYGOTE_MESSAGE_TYPE_SIGCHLD},
+                 .payload = {.pid = pid, .uid = uid, .status = status}};
+        if (TEMP_FAILURE_RETRY(
+                    sendto(socketFd, &data, sizeof(data), 0,
+                           reinterpret_cast<const struct sockaddr*>(&kSystemServerSockAddr),
+                           sizeof(kSystemServerSockAddr))) == -1) {
+            async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+                                  "Zygote failed to write to system_server FD: %s",
+                                  strerror(errno));
+        }
+    }
+}
+
 // This signal handler is for zygote mode, since the zygote must reap its children
-static void SigChldHandler(int /*signal_number*/) {
-  pid_t pid;
-  int status;
-  int64_t usaps_removed = 0;
+static void SigChldHandler(int /*signal_number*/, siginfo_t* info, void* /*ucontext*/) {
+    pid_t pid;
+    int status;
+    int64_t usaps_removed = 0;
 
-  // It's necessary to save and restore the errno during this function.
-  // Since errno is stored per thread, changing it here modifies the errno
-  // on the thread on which this signal handler executes. If a signal occurs
-  // between a call and an errno check, it's possible to get the errno set
-  // here.
-  // See b/23572286 for extra information.
-  int saved_errno = errno;
+    // It's necessary to save and restore the errno during this function.
+    // Since errno is stored per thread, changing it here modifies the errno
+    // on the thread on which this signal handler executes. If a signal occurs
+    // between a call and an errno check, it's possible to get the errno set
+    // here.
+    // See b/23572286 for extra information.
+    int saved_errno = errno;
 
-  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
-     // Log process-death status that we care about.
-    if (WIFEXITED(status)) {
-      async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
-                            "Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
+    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+        // Notify system_server that we received a SIGCHLD
+        sendSigChildStatus(pid, info->si_uid, status);
+        // Log process-death status that we care about.
+        if (WIFEXITED(status)) {
+            async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG, "Process %d exited cleanly (%d)", pid,
+                                  WEXITSTATUS(status));
 
-      // Check to see if the PID is in the USAP pool and remove it if it is.
-      if (RemoveUsapTableEntry(pid)) {
-        ++usaps_removed;
-      }
-    } else if (WIFSIGNALED(status)) {
-      async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
-                            "Process %d exited due to signal %d (%s)%s", pid,
-                            WTERMSIG(status), strsignal(WTERMSIG(status)),
-                            WCOREDUMP(status) ? "; core dumped" : "");
+            // Check to see if the PID is in the USAP pool and remove it if it is.
+            if (RemoveUsapTableEntry(pid)) {
+                ++usaps_removed;
+            }
+        } else if (WIFSIGNALED(status)) {
+            async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
+                                  "Process %d exited due to signal %d (%s)%s", pid,
+                                  WTERMSIG(status), strsignal(WTERMSIG(status)),
+                                  WCOREDUMP(status) ? "; core dumped" : "");
 
-      // If the process exited due to a signal other than SIGTERM, check to see
-      // if the PID is in the USAP pool and remove it if it is.  If the process
-      // was closed by the Zygote using SIGTERM then the USAP pool entry will
-      // have already been removed (see nativeEmptyUsapPool()).
-      if (WTERMSIG(status) != SIGTERM && RemoveUsapTableEntry(pid)) {
-        ++usaps_removed;
-      }
+            // If the process exited due to a signal other than SIGTERM, check to see
+            // if the PID is in the USAP pool and remove it if it is.  If the process
+            // was closed by the Zygote using SIGTERM then the USAP pool entry will
+            // have already been removed (see nativeEmptyUsapPool()).
+            if (WTERMSIG(status) != SIGTERM && RemoveUsapTableEntry(pid)) {
+                ++usaps_removed;
+            }
+        }
+
+        // If the just-crashed process is the system_server, bring down zygote
+        // so that it is restarted by init and system server will be restarted
+        // from there.
+        if (pid == gSystemServerPid) {
+            async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+                                  "Exit zygote because system server (pid %d) has terminated", pid);
+            kill(getpid(), SIGKILL);
+        }
     }
 
-    // If the just-crashed process is the system_server, bring down zygote
-    // so that it is restarted by init and system server will be restarted
-    // from there.
-    if (pid == gSystemServerPid) {
-      async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
-                            "Exit zygote because system server (pid %d) has terminated", pid);
-      kill(getpid(), SIGKILL);
+    // Note that we shouldn't consider ECHILD an error because
+    // the secondary zygote might have no children left to wait for.
+    if (pid < 0 && errno != ECHILD) {
+        async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, "Zygote SIGCHLD error in waitpid: %s",
+                              strerror(errno));
     }
-  }
 
-  // Note that we shouldn't consider ECHILD an error because
-  // the secondary zygote might have no children left to wait for.
-  if (pid < 0 && errno != ECHILD) {
-    async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG,
-                          "Zygote SIGCHLD error in waitpid: %s", strerror(errno));
-  }
-
-  if (usaps_removed > 0) {
-    if (TEMP_FAILURE_RETRY(write(gUsapPoolEventFD, &usaps_removed, sizeof(usaps_removed))) == -1) {
-      // If this write fails something went terribly wrong.  We will now kill
-      // the zygote and let the system bring it back up.
-      async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
-                            "Zygote failed to write to USAP pool event FD: %s",
-                            strerror(errno));
-      kill(getpid(), SIGKILL);
+    if (usaps_removed > 0) {
+        if (TEMP_FAILURE_RETRY(write(gUsapPoolEventFD, &usaps_removed, sizeof(usaps_removed))) ==
+            -1) {
+            // If this write fails something went terribly wrong.  We will now kill
+            // the zygote and let the system bring it back up.
+            async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
+                                  "Zygote failed to write to USAP pool event FD: %s",
+                                  strerror(errno));
+            kill(getpid(), SIGKILL);
+        }
     }
-  }
 
-  errno = saved_errno;
+    errno = saved_errno;
 }
 
 // Configures the SIGCHLD/SIGHUP handlers for the zygote process. This is
@@ -441,12 +501,11 @@
 // This ends up being called repeatedly before each fork(), but there's
 // no real harm in that.
 static void SetSignalHandlers() {
-  struct sigaction sig_chld = {};
-  sig_chld.sa_handler = SigChldHandler;
+    struct sigaction sig_chld = {.sa_flags = SA_SIGINFO, .sa_sigaction = SigChldHandler};
 
-  if (sigaction(SIGCHLD, &sig_chld, nullptr) < 0) {
-    ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
-  }
+    if (sigaction(SIGCHLD, &sig_chld, nullptr) < 0) {
+        ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
+    }
 
   struct sigaction sig_hup = {};
   sig_hup.sa_handler = SIG_IGN;
@@ -1049,6 +1108,9 @@
 
     // Turn fdsan back on.
     android_fdsan_set_error_level(fdsan_error_level);
+
+    // Reset the fd to the unsolicited zygote socket
+    gSystemServerSocketFd = -1;
   } else {
     ALOGD("Forked child process %d", pid);
   }
@@ -1094,19 +1156,19 @@
       fail_fn(CREATE_ERROR("Unexpected error in getAppDataDirName: %s", strerror(errno)));
       return nullptr;
     }
-    // Directory doesn't exist, try to search the name from inode
-    DIR* dir = opendir(parent_path.data());
-    if (dir == nullptr) {
-      fail_fn(CREATE_ERROR("Failed to opendir %s", parent_path.data()));
-    }
-    struct dirent* ent;
-    while ((ent = readdir(dir))) {
-      if (ent->d_ino == ce_data_inode) {
-        closedir(dir);
-        return ent->d_name;
+    {
+      // Directory doesn't exist, try to search the name from inode
+      std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(parent_path.data()), closedir);
+      if (dir == nullptr) {
+        fail_fn(CREATE_ERROR("Failed to opendir %s", parent_path.data()));
+      }
+      struct dirent* ent;
+      while ((ent = readdir(dir.get()))) {
+        if (ent->d_ino == ce_data_inode) {
+          return ent->d_name;
+        }
       }
     }
-    closedir(dir);
 
     // Fallback due to b/145989852, ce_data_inode stored in package manager may be corrupted
     // if ino_t is 32 bits.
@@ -1117,19 +1179,18 @@
       fixed_ce_data_inode = ((ce_data_inode >> 32) & LOWER_HALF_WORD_MASK);
     }
     if (fixed_ce_data_inode != 0) {
-      dir = opendir(parent_path.data());
+      std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(parent_path.data()), closedir);
       if (dir == nullptr) {
         fail_fn(CREATE_ERROR("Failed to opendir %s", parent_path.data()));
       }
-      while ((ent = readdir(dir))) {
+      struct dirent* ent;
+      while ((ent = readdir(dir.get()))) {
         if (ent->d_ino == fixed_ce_data_inode) {
           long long d_ino = ent->d_ino;
           ALOGW("Fallback success inode %lld -> %lld", ce_data_inode, d_ino);
-          closedir(dir);
           return ent->d_name;
         }
       }
-      closedir(dir);
     }
     // Fallback done
 
@@ -1410,8 +1471,7 @@
 
   // Create profile directory for this user.
   std::string actualCurUserProfile = StringPrintf("%s/%d", kCurProfileDirPath, user_id);
-  PrepareDir(actualCurUserProfile.c_str(), DEFAULT_DATA_DIR_PERMISSION, AID_ROOT, AID_ROOT,
-      fail_fn);
+  PrepareDir(actualCurUserProfile, DEFAULT_DATA_DIR_PERMISSION, AID_ROOT, AID_ROOT, fail_fn);
 
   for (int i = 0; i < size; i += 3) {
     jstring package_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i));
@@ -1608,6 +1668,10 @@
     }
   }
 
+  if (is_child_zygote) {
+      initUnsolSocketToSystemServer();
+  }
+
   env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
                             is_system_server, is_child_zygote, managed_instruction_set);
 
@@ -1873,6 +1937,11 @@
       fds_to_ignore.push_back(gUsapPoolEventFD);
     }
 
+    if (gSystemServerSocketFd != -1) {
+        fds_to_close.push_back(gSystemServerSocketFd);
+        fds_to_ignore.push_back(gSystemServerSocketFd);
+    }
+
     pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
 
     if (pid == 0) {
@@ -1899,6 +1968,11 @@
     fds_to_ignore.push_back(gUsapPoolEventFD);
   }
 
+  if (gSystemServerSocketFd != -1) {
+      fds_to_close.push_back(gSystemServerSocketFd);
+      fds_to_ignore.push_back(gSystemServerSocketFd);
+  }
+
   pid_t pid = ForkCommon(env, true,
                          fds_to_close,
                          fds_to_ignore,
@@ -1969,6 +2043,9 @@
   fds_to_close.push_back(gZygoteSocketFD);
   fds_to_close.push_back(gUsapPoolEventFD);
   fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end());
+  if (gSystemServerSocketFd != -1) {
+      fds_to_close.push_back(gSystemServerSocketFd);
+  }
 
   fds_to_ignore.push_back(gZygoteSocketFD);
   fds_to_ignore.push_back(gUsapPoolSocketFD);
@@ -1976,6 +2053,9 @@
   fds_to_ignore.push_back(read_pipe_fd);
   fds_to_ignore.push_back(write_pipe_fd);
   fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
+  if (gSystemServerSocketFd != -1) {
+      fds_to_ignore.push_back(gSystemServerSocketFd);
+  }
 
   pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore,
                               is_priority_fork == JNI_TRUE);
@@ -2074,6 +2154,8 @@
     ALOGE("Unable to fetch USAP pool socket file descriptor");
   }
 
+  initUnsolSocketToSystemServer();
+
   /*
    * Security Initialization
    */
@@ -2200,43 +2282,81 @@
   setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
 }
 
+static jint com_android_internal_os_Zygote_nativeParseSigChld(JNIEnv* env, jclass, jbyteArray in,
+                                                              jint length, jintArray out) {
+    if (length != sizeof(struct UnsolicitedZygoteMessageSigChld)) {
+        // Apparently it's not the message we are expecting.
+        return -1;
+    }
+    if (in == nullptr || out == nullptr) {
+        // Invalid parameter
+        jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
+        return -1;
+    }
+    ScopedByteArrayRO source(env, in);
+    if (source.size() < length) {
+        // Invalid parameter
+        jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
+        return -1;
+    }
+    const struct UnsolicitedZygoteMessageSigChld* msg =
+            reinterpret_cast<const struct UnsolicitedZygoteMessageSigChld*>(source.get());
+
+    switch (msg->header.type) {
+        case UNSOLICITED_ZYGOTE_MESSAGE_TYPE_SIGCHLD: {
+            ScopedIntArrayRW buf(env, out);
+            if (buf.size() != 3) {
+                jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
+                return UNSOLICITED_ZYGOTE_MESSAGE_TYPE_RESERVED;
+            }
+            buf[0] = msg->payload.pid;
+            buf[1] = msg->payload.uid;
+            buf[2] = msg->payload.status;
+            return 3;
+        }
+        default:
+            break;
+    }
+    return -1;
+}
+
 static const JNINativeMethod gMethods[] = {
-    { "nativeForkAndSpecialize",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;)I",
-      (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
-    { "nativeForkSystemServer", "(II[II[[IJJ)I",
-      (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
-    { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
-      (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },
-    { "nativePreApplicationInit", "()V",
-      (void *) com_android_internal_os_Zygote_nativePreApplicationInit },
-    { "nativeInstallSeccompUidGidFilter", "(II)V",
-      (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
-    { "nativeForkUsap", "(II[IZ)I",
-      (void *) com_android_internal_os_Zygote_nativeForkUsap },
-    { "nativeSpecializeAppProcess",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;)V",
-      (void *) com_android_internal_os_Zygote_nativeSpecializeAppProcess },
-    { "nativeInitNativeState", "(Z)V",
-      (void *) com_android_internal_os_Zygote_nativeInitNativeState },
-    { "nativeGetUsapPipeFDs", "()[I",
-      (void *) com_android_internal_os_Zygote_nativeGetUsapPipeFDs },
-    { "nativeRemoveUsapTableEntry", "(I)Z",
-      (void *) com_android_internal_os_Zygote_nativeRemoveUsapTableEntry },
-    { "nativeGetUsapPoolEventFD", "()I",
-      (void *) com_android_internal_os_Zygote_nativeGetUsapPoolEventFD },
-    { "nativeGetUsapPoolCount", "()I",
-      (void *) com_android_internal_os_Zygote_nativeGetUsapPoolCount },
-    { "nativeEmptyUsapPool", "()V",
-      (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
-    { "nativeDisableExecuteOnly", "()Z",
-      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly },
-    { "nativeBlockSigTerm", "()V",
-      (void* ) com_android_internal_os_Zygote_nativeBlockSigTerm },
-    { "nativeUnblockSigTerm", "()V",
-      (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm },
-    { "nativeBoostUsapPriority", "()V",
-      (void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority }
+        {"nativeForkAndSpecialize",
+         "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/"
+         "String;Z[Ljava/lang/String;)I",
+         (void*)com_android_internal_os_Zygote_nativeForkAndSpecialize},
+        {"nativeForkSystemServer", "(II[II[[IJJ)I",
+         (void*)com_android_internal_os_Zygote_nativeForkSystemServer},
+        {"nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
+         (void*)com_android_internal_os_Zygote_nativeAllowFileAcrossFork},
+        {"nativePreApplicationInit", "()V",
+         (void*)com_android_internal_os_Zygote_nativePreApplicationInit},
+        {"nativeInstallSeccompUidGidFilter", "(II)V",
+         (void*)com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter},
+        {"nativeForkUsap", "(II[IZ)I", (void*)com_android_internal_os_Zygote_nativeForkUsap},
+        {"nativeSpecializeAppProcess",
+         "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/"
+         "String;Z[Ljava/lang/String;)V",
+         (void*)com_android_internal_os_Zygote_nativeSpecializeAppProcess},
+        {"nativeInitNativeState", "(Z)V",
+         (void*)com_android_internal_os_Zygote_nativeInitNativeState},
+        {"nativeGetUsapPipeFDs", "()[I",
+         (void*)com_android_internal_os_Zygote_nativeGetUsapPipeFDs},
+        {"nativeRemoveUsapTableEntry", "(I)Z",
+         (void*)com_android_internal_os_Zygote_nativeRemoveUsapTableEntry},
+        {"nativeGetUsapPoolEventFD", "()I",
+         (void*)com_android_internal_os_Zygote_nativeGetUsapPoolEventFD},
+        {"nativeGetUsapPoolCount", "()I",
+         (void*)com_android_internal_os_Zygote_nativeGetUsapPoolCount},
+        {"nativeEmptyUsapPool", "()V", (void*)com_android_internal_os_Zygote_nativeEmptyUsapPool},
+        {"nativeDisableExecuteOnly", "()Z",
+         (void*)com_android_internal_os_Zygote_nativeDisableExecuteOnly},
+        {"nativeBlockSigTerm", "()V", (void*)com_android_internal_os_Zygote_nativeBlockSigTerm},
+        {"nativeUnblockSigTerm", "()V", (void*)com_android_internal_os_Zygote_nativeUnblockSigTerm},
+        {"nativeBoostUsapPriority", "()V",
+         (void*)com_android_internal_os_Zygote_nativeBoostUsapPriority},
+        {"nativeParseSigChld", "([BI[I)I",
+         (void*)com_android_internal_os_Zygote_nativeParseSigChld},
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/proto/android/app/appexitinfo.proto b/core/proto/android/app/appexitinfo.proto
new file mode 100644
index 0000000..e23f150
--- /dev/null
+++ b/core/proto/android/app/appexitinfo.proto
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+option java_multiple_files = true;
+
+package android.app;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+/**
+ * An android.app.ApplicationExitInfo object.
+ */
+message ApplicationExitInfoProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 pid = 1;
+    optional int32 real_uid = 2;
+    optional int32 package_uid = 3;
+    optional int32 defining_uid = 4;
+    optional string process_name = 5;
+    optional int32 connection_group = 6;
+
+    enum ReasonCode {
+        /**
+         * Application process died due to unknown reason.
+         */
+        REASON_UNKNOWN = 0;
+
+        /**
+         * Application process exit normally by itself, for example,
+         * via {@link android.os.Process#exit}; {@link #status} will specify the exit code.
+         *
+         * <p>Applications should normally not do this, as the system has a better knowledge
+         * in terms of process management.</p>
+         */
+        REASON_EXIT_SELF = 1;
+
+        /**
+         * Application process died due to the result of an OS signal; for example,
+         * {@link android.os.Process#SIGNAL_KILL}; {@link #status} will specify the signum.
+         */
+        REASON_SIGNALED = 2;
+
+        /**
+         * Application process was killed by the system low memory killer, meaning the system was
+         * under memory pressure at the time of kill.
+         */
+        REASON_LOW_MEMORY = 3;
+
+        /**
+         * Application process died because of an unhandled exception in Java code.
+         */
+        REASON_CRASH = 4;
+
+        /**
+         * Application process died because it's crashed due to a native code crash.
+         */
+        REASON_CRASH_NATIVE = 5;
+
+        /**
+         * Application process was killed due to being unresponsive (ANR).
+         */
+        REASON_ANR = 6;
+
+        /**
+         * Application process was killed because it took too long to attach to the system
+         * during the start.
+         */
+        REASON_INITIALIZATION_FAILURE = 7;
+
+        /**
+         * Application process was killed because of initialization failure,
+         * for example, it took too long to attach to the system during the start,
+         * or there was an error during initialization.
+         */
+        REASON_PERMISSION_CHANGE = 8;
+
+        /**
+         * Application process was killed by the activity manager due to excessive resource usage.
+         */
+        REASON_EXCESSIVE_RESOURCE_USAGE = 9;
+
+        /**
+         * Application process was killed by the system for various other reasons,
+         * for example, the application package got disabled by the user;
+         * {@link #description} will specify the cause given by the system.
+         */
+        REASON_OTHER = 10;
+
+    }
+    optional ReasonCode reason = 7;
+
+    enum SubReason {
+        /**
+         * Application process kills subReason is unknown.
+         */
+        SUBREASON_UNKNOWN = 0;
+
+        /**
+         * Application process was killed because user quit it on the "wait for debugger" dialog.
+         */
+        SUBREASON_WAIT_FOR_DEBUGGER = 1;
+
+        /**
+         * Application process was killed by the activity manager because there were too many cached
+         * processes.
+         */
+        SUBREASON_TOO_MANY_CACHED = 2;
+
+        /**
+         * Application process was killed by the activity manager because there were too many empty
+         * processes.
+         */
+        SUBREASON_TOO_MANY_EMPTY = 3;
+
+        /**
+         * Application process was killed by the activity manager because there were too many cached
+         * processes and this process had been in empty state for a long time.
+         */
+        SUBREASON_TRIM_EMPTY = 4;
+
+        /**
+         * Application process was killed by the activity manager because system was on
+         * memory pressure and this process took large amount of cached memory.
+         */
+        SUBREASON_LARGE_CACHED = 5;
+
+        /**
+         * Application process was killed by the activity manager because the system was on
+         * low memory pressure for a significant amount of time since last idle.
+         */
+        SUBREASON_MEMORY_PRESSURE = 6;
+
+        /**
+         * Application process was killed by the activity manager due to excessive CPU usage.
+         */
+        SUBREASON_EXCESSIVE_CPU = 7;
+    }
+
+    optional SubReason sub_reason = 8;
+
+    optional int32 status = 9;
+
+    enum Importance {
+        option allow_alias = true;
+        /**
+         * Keep sync with the definitions in
+         * {@link android.app.ActivityManager.RunningAppProcessInfo}
+         */
+        IMPORTANCE_FOREGROUND = 100;
+        IMPORTANCE_FOREGROUND_SERVICE = 125;
+        IMPORTANCE_TOP_SLEEPING_PRE_28 = 150;
+        IMPORTANCE_VISIBLE = 200;
+        IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
+        IMPORTANCE_PERCEPTIBLE = 230;
+        IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
+        IMPORTANCE_SERVICE = 300;
+        IMPORTANCE_TOP_SLEEPING = 325;
+        IMPORTANCE_CANT_SAVE_STATE = 350;
+        IMPORTANCE_CACHED = 400;
+        IMPORTANCE_BACKGROUND = 400;
+        IMPORTANCE_EMPTY = 500;
+        IMPORTANCE_GONE = 1000;
+    }
+
+    optional Importance importance = 10;
+    optional int32 pss = 11;
+    optional int32 rss = 12;
+    optional int64 timestamp = 13;
+    optional string description = 14;
+}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index cd3887e..a85c8f4 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2557,4 +2557,9 @@
     // OS: R
     DND_PEOPLE = 1823;
 
+    // OPEN: Settings > Apps and notifications > App info > one of any app > Open by default
+    //       > Open supported links
+    // CATEGORY: SETTINGS
+    // OS: R
+    OPEN_SUPPORTED_LINKS = 1824;
 }
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 7835016..77d4e87 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -188,6 +188,7 @@
         optional SettingProto pulse_on_long_press = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto pulse_on_double_tap = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto pulse_on_tap = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto suppress = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Doze doze = 21;
 
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index c79f314..126d445 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -19,6 +19,7 @@
 package com.android.server.am;
 
 import "frameworks/base/core/proto/android/app/activitymanager.proto";
+import "frameworks/base/core/proto/android/app/appexitinfo.proto";
 import "frameworks/base/core/proto/android/app/enums.proto";
 import "frameworks/base/core/proto/android/app/notification.proto";
 import "frameworks/base/core/proto/android/app/profilerinfo.proto";
@@ -1082,3 +1083,23 @@
     optional .android.util.Duration started_time = 4;
     optional string started_package = 5;
 }
+
+// sync with com.android.server.am.am.ProcessList.java
+message AppsExitInfoProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int64 last_update_timestamp = 1;
+    message Package {
+        option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+        optional string package_name = 1;
+        message User {
+            option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+            optional int32 uid = 1;
+            repeated .android.app.ApplicationExitInfoProto app_exit_info = 2;
+        }
+        repeated User users = 2;
+    }
+    repeated Package packages = 2;
+}
diff --git a/core/proto/android/server/animationadapter.proto b/core/proto/android/server/animationadapter.proto
index 70627ed..c6925f4 100644
--- a/core/proto/android/server/animationadapter.proto
+++ b/core/proto/android/server/animationadapter.proto
@@ -50,6 +50,7 @@
     optional WindowAnimationSpecProto window = 1;
     optional MoveAnimationSpecProto move = 2;
     optional AlphaAnimationSpecProto alpha = 3;
+    optional RotationAnimationSpecProto rotate = 4;
 }
 
 /* represents WindowAnimationSpec */
@@ -76,3 +77,12 @@
     optional float to = 2;
     optional int64 duration_ms = 3;
 }
+
+/* represents RotationAnimationSpec */
+message RotationAnimationSpecProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional float start_luma = 1;
+    optional float end_luma = 2;
+    optional int64 duration_ms = 3;
+}
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
index 0ae11a1..0f03e69 100644
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
@@ -156,4 +156,5 @@
   SET_PACKAGES_PROTECTED = 129;
   SET_FACTORY_RESET_PROTECTION = 130;
   SET_COMMON_CRITERIA_MODE = 131;
+  ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS = 132;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b27348..a8da2d9 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -563,10 +563,12 @@
 
     <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
 
-    <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_INCOMING_CALL" />
     <protected-broadcast android:name="com.android.phone.SIP_ADD_PHONE" />
-    <protected-broadcast android:name="com.android.phone.SIP_REMOVE_PHONE" />
-    <protected-broadcast android:name="com.android.phone.SIP_CALL_OPTION_CHANGED" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_REMOVE_PROFILE" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_SERVICE_UP" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_CALL_OPTION_CHANGED" />
+    <protected-broadcast android:name="android.net.sip.action.START_SIP" />
 
     <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_CONNECTED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED" />
@@ -2209,12 +2211,12 @@
 
     <!-- Must be required by a NetworkService to ensure that only the
          system can bind to it.
-         <p>Protection level: signature
+         <p>Protection level: signature|telephony
          @SystemApi
          @hide
     -->
     <permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE"
-                android:protectionLevel="signature" />
+                android:protectionLevel="signature|telephony" />
 
     <!-- @SystemApi Allows an application to manage embedded subscriptions (those on a eUICC)
          through EuiccManager APIs.
@@ -2232,6 +2234,14 @@
     <permission android:name="android.permission.BIND_EUICC_SERVICE"
                 android:protectionLevel="signature|telephony" />
 
+    <!-- Required for reading information about carrier apps from SystemConfigManager.
+         <p>Protection level: signature|telephony
+         @SystemApi
+         @hide
+    -->
+    <permission android:name="android.permission.READ_CARRIER_APP_INFO"
+        android:protectionLevel="signature|telephony" />
+
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
@@ -2359,7 +2369,7 @@
     <permission android:name="android.permission.MANAGE_USERS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @hide Allows an application to create, remove users and get the list of
+    <!-- @SystemApi @hide Allows an application to create, remove users and get the list of
          users on the device. Applications holding this permission can only create restricted,
          guest, managed, demo, and ephemeral users. For creating other kind of users,
          {@link android.Manifest.permission#MANAGE_USERS} is needed.
diff --git a/core/res/res/anim/screen_rotate_0_enter.xml b/core/res/res/anim/screen_rotate_0_enter.xml
index 93cf365..629be7e 100644
--- a/core/res/res/anim/screen_rotate_0_enter.xml
+++ b/core/res/res/anim/screen_rotate_0_enter.xml
@@ -1,25 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
-    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:duration="@android:integer/config_shortAnimTime" />
+    android:shareInterpolator="false">
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:interpolator="@interpolator/screen_rotation_alpha_in"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:duration="@android:integer/config_screen_rotation_fade_in" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_0_exit.xml b/core/res/res/anim/screen_rotate_0_exit.xml
index 37d5a411..fa046a0 100644
--- a/core/res/res/anim/screen_rotate_0_exit.xml
+++ b/core/res/res/anim/screen_rotate_0_exit.xml
@@ -1,22 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
+    android:shareInterpolator="false">
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+        android:interpolator="@interpolator/screen_rotation_alpha_out"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:duration="@android:integer/config_screen_rotation_fade_out" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_0_frame.xml b/core/res/res/anim/screen_rotate_0_frame.xml
deleted file mode 100644
index 5ea9bf8..0000000
--- a/core/res/res/anim/screen_rotate_0_frame.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
-    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:duration="@android:integer/config_shortAnimTime" />
-</set>
diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml
index 688a8d5..889a615 100644
--- a/core/res/res/anim/screen_rotate_180_enter.xml
+++ b/core/res/res/anim/screen_rotate_180_enter.xml
@@ -18,11 +18,11 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
+    android:shareInterpolator="false">
     <rotate android:fromDegrees="180" android:toDegrees="0"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+        android:pivotX="50%" android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="@android:integer/config_screen_rotation_total_180" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml
index 58a1868..766fcfa 100644
--- a/core/res/res/anim/screen_rotate_180_exit.xml
+++ b/core/res/res/anim/screen_rotate_180_exit.xml
@@ -18,11 +18,11 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
+    android:shareInterpolator="false">
     <rotate android:fromDegrees="0" android:toDegrees="-180"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+        android:pivotX="50%" android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="@android:integer/config_screen_rotation_total_180" />
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/screen_rotate_alpha.xml b/core/res/res/anim/screen_rotate_alpha.xml
index c49ef9c..2cac982 100644
--- a/core/res/res/anim/screen_rotate_alpha.xml
+++ b/core/res/res/anim/screen_rotate_alpha.xml
@@ -20,8 +20,8 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
     <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-           android:interpolator="@interpolator/decelerate_quint"
+           android:interpolator="@interpolator/screen_rotation_alpha_out"
            android:fillEnabled="true"
            android:fillBefore="true" android:fillAfter="true"
-           android:duration="@android:integer/config_mediumAnimTime" />
+           android:duration="@android:integer/config_screen_rotation_fade_out" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_enter.xml b/core/res/res/anim/screen_rotate_minus_90_enter.xml
index b16d5fc..87fd25e 100644
--- a/core/res/res/anim/screen_rotate_minus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml
@@ -18,19 +18,17 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
-    <!-- Version for two-phase anim
+    android:shareInterpolator="false">
     <rotate android:fromDegrees="-90" android:toDegrees="0"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_longAnimTime" />
-    -->
-    <rotate android:fromDegrees="-90" android:toDegrees="0"
-            android:pivotX="50%" android:pivotY="50%"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:duration="@android:integer/config_mediumAnimTime" />
+        android:pivotX="50%" android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="@android:integer/config_screen_rotation_total_90" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/screen_rotation_alpha_in"
+        android:startOffset="@android:integer/config_screen_rotation_fade_in_delay"
+        android:duration="@android:integer/config_screen_rotation_fade_in" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_exit.xml b/core/res/res/anim/screen_rotate_minus_90_exit.xml
index 0927dd3..c3aee14 100644
--- a/core/res/res/anim/screen_rotate_minus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml
@@ -18,26 +18,16 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
-    <!-- Version for two-phase animation
+    android:shareInterpolator="false">
     <rotate android:fromDegrees="0" android:toDegrees="90"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_longAnimTime" />
-    -->
-    <scale android:fromXScale="100%" android:toXScale="100%p"
-            android:fromYScale="100%" android:toYScale="100%p"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    <rotate android:fromDegrees="0" android:toDegrees="90"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+        android:pivotX="50%" android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="@android:integer/config_screen_rotation_total_90" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/screen_rotation_alpha_out"
+        android:duration="@android:integer/config_screen_rotation_fade_out" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_enter.xml b/core/res/res/anim/screen_rotate_plus_90_enter.xml
index 86a8d24..8849db4 100644
--- a/core/res/res/anim/screen_rotate_plus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml
@@ -18,19 +18,16 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
-    <!-- Version for two-phase animation
+    android:shareInterpolator="false">
     <rotate android:fromDegrees="90" android:toDegrees="0"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_longAnimTime" />
-    -->
-    <rotate android:fromDegrees="90" android:toDegrees="0"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+        android:pivotX="50%" android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="@android:integer/config_screen_rotation_total_90" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:interpolator="@interpolator/screen_rotation_alpha_in"
+        android:startOffset="@android:integer/config_screen_rotation_fade_in_delay"
+        android:duration="@android:integer/config_screen_rotation_fade_in" />
 </set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_exit.xml b/core/res/res/anim/screen_rotate_plus_90_exit.xml
index fd786f9..de84c3b 100644
--- a/core/res/res/anim/screen_rotate_plus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml
@@ -18,26 +18,16 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false">
-    <!-- Version for two-phase animation
+    android:shareInterpolator="false">
     <rotate android:fromDegrees="0" android:toDegrees="-90"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_longAnimTime" />
-    -->
-    <scale android:fromXScale="100%" android:toXScale="100%p"
-            android:fromYScale="100%" android:toYScale="100%p"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
-    <rotate android:fromDegrees="0" android:toDegrees="-90"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:fillEnabled="true"
-            android:fillBefore="true" android:fillAfter="true"
-            android:duration="@android:integer/config_mediumAnimTime" />
+        android:pivotX="50%" android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="@android:integer/config_screen_rotation_total_90" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+        android:interpolator="@interpolator/screen_rotation_alpha_out"
+        android:fillEnabled="true"
+        android:fillBefore="true" android:fillAfter="true"
+        android:duration="@android:integer/config_screen_rotation_fade_out" />
 </set>
diff --git a/core/res/res/drawable-hdpi/ic_accessibility_magnification.png b/core/res/res/drawable-hdpi/ic_accessibility_magnification.png
deleted file mode 100755
index a91bc6e..0000000
--- a/core/res/res/drawable-hdpi/ic_accessibility_magnification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_accessibility_magnification.png b/core/res/res/drawable-mdpi/ic_accessibility_magnification.png
deleted file mode 100755
index 9ec5107..0000000
--- a/core/res/res/drawable-mdpi/ic_accessibility_magnification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_accessibility_magnification.png b/core/res/res/drawable-xhdpi/ic_accessibility_magnification.png
deleted file mode 100755
index 0b3a32e..0000000
--- a/core/res/res/drawable-xhdpi/ic_accessibility_magnification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_accessibility_magnification.png b/core/res/res/drawable-xxhdpi/ic_accessibility_magnification.png
deleted file mode 100755
index 3eeb1c9..0000000
--- a/core/res/res/drawable-xxhdpi/ic_accessibility_magnification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_accessibility_magnification.png b/core/res/res/drawable-xxxhdpi/ic_accessibility_magnification.png
deleted file mode 100755
index 7d37612..0000000
--- a/core/res/res/drawable-xxxhdpi/ic_accessibility_magnification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_accessibility_color_correction.xml b/core/res/res/drawable/ic_accessibility_color_correction.xml
index 02fa4b8..ed09d57 100644
--- a/core/res/res/drawable/ic_accessibility_color_correction.xml
+++ b/core/res/res/drawable/ic_accessibility_color_correction.xml
@@ -1,3 +1,18 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
 <vector android:height="24dp" android:viewportHeight="192"
     android:viewportWidth="192" android:width="24dp"
     xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
diff --git a/core/res/res/drawable/ic_accessibility_color_inversion.xml b/core/res/res/drawable/ic_accessibility_color_inversion.xml
index 97b30b0..d69a169 100644
--- a/core/res/res/drawable/ic_accessibility_color_inversion.xml
+++ b/core/res/res/drawable/ic_accessibility_color_inversion.xml
@@ -1,3 +1,18 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
 <vector android:height="24dp" android:viewportHeight="192"
     android:viewportWidth="192" android:width="24dp"
     xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
diff --git a/core/res/res/drawable/ic_accessibility_magnification.xml b/core/res/res/drawable/ic_accessibility_magnification.xml
new file mode 100644
index 0000000..5dab479
--- /dev/null
+++ b/core/res/res/drawable/ic_accessibility_magnification.xml
@@ -0,0 +1,114 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="192"
+    android:viewportHeight="192">
+  <path
+      android:pathData="M96,104m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"
+      android:fillColor="#F50057"/>
+  <path
+      android:pathData="M178.57,70.06l-73.81,-58.94C99.6,7.01 92.35,6.96 87.15,11L13.59,68.14C8.87,71.8 6.9,78.02 8.61,83.77l28.53,89.97c1.83,6.09 7.39,10.26 13.7,10.26h90.38c6.28,0 11.82,-4.13 13.67,-10.19l0.69,-2.13l-34.94,-34.88v-4.7l-0.96,-0.99c-6.33,5.54 -14.61,8.9 -23.68,8.9c-19.89,0 -36.02,-16.12 -36.02,-36.01S76.11,68 96,68s36.01,16.12 36.01,36.01c0,8.68 -3.08,16.65 -8.2,22.87l1.05,1.01h4.7l30.34,30.39l23.47,-72.65C185.1,79.94 183.2,73.76 178.57,70.06z"
+      android:fillColor="#F50057"/>
+  <path
+      android:pathData="M65.25,73c0,0 -16.75,31.96 -9.25,45.1s21.02,29.15 40.01,32.65s32.99,10.5 39.99,14s19.58,6.93 19.58,6.93s-5.34,-9.49 4.32,-13.4c0.73,-3.53 -11.9,-42.35 -11.9,-42.35L127.92,73L81.79,62.25L65.25,73z"
+      android:fillColor="#F50057"/>
+  <path
+      android:pathData="M155.33,171.43l-0.44,1.37c-1.85,6.06 -7.39,10.19 -13.67,10.19H50.84c-6.31,0 -11.87,-4.17 -13.7,-10.26L8.61,82.77c-0.36,-1.22 -0.55,-2.46 -0.59,-3.69c-0.06,1.56 0.13,3.14 0.59,4.69l28.53,89.97c1.83,6.09 7.39,10.26 13.7,10.26h90.38c6.28,0 11.82,-4.13 13.67,-10.19l0.69,-2.13L155.33,171.43z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M183.37,84.63l-23.71,73.41l0.24,0.24l23.47,-72.66c0.48,-1.57 0.67,-3.17 0.61,-4.75C183.94,82.13 183.74,83.39 183.37,84.63z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M155.57,171.67l-34.93,-34.87v-4.7l-0.96,-0.99c-6.33,5.54 -14.61,8.9 -23.68,8.9c-9.81,0 -18.71,-3.93 -25.2,-10.29L125.07,184h16.14c6.28,0 11.81,-4.13 13.67,-10.19L155.57,171.67z">
+    <aapt:attr name="android:fillColor">
+      <gradient
+          android:startY="104.215"
+          android:startX="69.035"
+          android:endY="173.8946"
+          android:endX="138.7146"
+          android:type="linear">
+        <item android:offset="0" android:color="#333E2723"/>
+        <item android:offset="1" android:color="#003E2723"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+  <path
+      android:pathData="M132.01,104.01c0,8.68 -3.08,16.65 -8.2,22.87l1.05,1.01h4.7l30.34,30.39L170,127l-49,-49.03l-0.19,-0.04C127.71,84.49 132.01,93.74 132.01,104.01z">
+    <aapt:attr name="android:fillColor">
+      <gradient
+          android:startY="83.635"
+          android:startX="103.615"
+          android:endY="137.0219"
+          android:endX="157.0018"
+          android:type="linear">
+        <item android:offset="0" android:color="#333E2723"/>
+        <item android:offset="1" android:color="#003E2723"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+  <path
+      android:pathData="M124.27,127.32c4.85,-6.13 7.75,-13.88 7.75,-22.3c0,-0.16 -0.01,-0.31 -0.01,-0.47c-0.12,8.47 -3.17,16.24 -8.19,22.34L124.27,127.32z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M96.01,80.01c-13.25,0 -24,10.75 -24,24c0,0.17 0.01,0.33 0.01,0.5c0.27,-13.02 10.91,-23.5 23.99,-23.5s23.72,10.48 23.99,23.5c0,-0.17 0.01,-0.33 0.01,-0.5C120.01,90.76 109.26,80.01 96.01,80.01z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M155.58,171.68l-34.93,-34.87l0,1l34.68,34.62z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M119.69,131.12c-6.33,5.54 -14.61,8.9 -23.68,8.9c-9.97,0 -19,-4.06 -25.52,-10.61h-0.01l5.59,5.59c5.71,3.8 12.57,6.03 19.94,6.03c9.07,0 17.35,-3.36 23.68,-8.9l0.96,0.99v-1L119.69,131.12z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#3E2723"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M13.59,69.14L87.15,12c5.2,-4.04 12.45,-3.99 17.61,0.12l73.81,58.94c3.36,2.68 5.27,6.67 5.41,10.82c0.15,-4.51 -1.79,-8.93 -5.41,-11.82l-73.81,-58.94C99.6,7.01 92.35,6.96 87.15,11L13.59,68.14c-3.72,2.88 -5.72,7.36 -5.57,11.94C8.17,75.85 10.14,71.81 13.59,69.14z"
+      android:strokeAlpha="0.2"
+      android:fillColor="#FFFFFF"
+      android:fillAlpha="0.2"/>
+  <path
+      android:pathData="M112,108h-12v12h-8v-12H80v-8h12V88h8v12h12V108z"
+      android:fillColor="#F8BBD0"/>
+  <path
+      android:pathData="M129.57,127.9h-4.7l-1.05,-1.01c5.12,-6.22 8.2,-14.19 8.2,-22.87c0,-19.89 -16.12,-36.01 -36.01,-36.01s-36.02,16.11 -36.02,36s16.13,36.01 36.02,36.01c9.07,0 17.35,-3.36 23.68,-8.9l0.96,0.99v4.7l34.93,34.87l4.33,-13.39L129.57,127.9zM96.01,128.01c-13.25,0 -24,-10.75 -24,-24s10.75,-24 24,-24s24,10.75 24,24S109.26,128.01 96.01,128.01z"
+      android:fillColor="#FFFFFF"/>
+  <path
+      android:pathData="M37.14,173.74L8.61,83.77C6.9,78.02 8.87,71.8 13.59,68.14L87.15,11c5.2,-4.04 12.45,-3.99 17.61,0.12l73.81,58.94c4.63,3.7 6.53,9.88 4.8,15.57l-28.48,88.18c-1.85,6.06 -7.39,10.19 -13.67,10.19H50.84C44.53,184 38.97,179.83 37.14,173.74z">
+    <aapt:attr name="android:fillColor">
+      <gradient
+          android:startY="53.3534"
+          android:startX="38.1466"
+          android:endY="178.712"
+          android:endX="163.5051"
+          android:type="linear">
+        <item android:offset="0" android:color="#19FFFFFF"/>
+        <item android:offset="1" android:color="#00FFFFFF"/>
+      </gradient>
+    </aapt:attr>
+  </path>
+</vector>
diff --git a/core/res/res/interpolator/screen_rotation_alpha_in.xml b/core/res/res/interpolator/screen_rotation_alpha_in.xml
new file mode 100644
index 0000000..9c566a7
--- /dev/null
+++ b/core/res/res/interpolator/screen_rotation_alpha_in.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:controlX1="0.15"
+    android:controlY1="0.45"
+    android:controlX2="0.33"
+    android:controlY2="1"/>
diff --git a/core/res/res/interpolator/screen_rotation_alpha_out.xml b/core/res/res/interpolator/screen_rotation_alpha_out.xml
new file mode 100644
index 0000000..73a37d4
--- /dev/null
+++ b/core/res/res/interpolator/screen_rotation_alpha_out.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:controlX1="0.57"
+    android:controlY1="0"
+    android:controlX2="0.71"
+    android:controlY2=".43"/>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 3dd5651..be0e588 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"by jou kalender in te gaan"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS-boodskappe te stuur en te bekyk"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Berging"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"toegang te verkry tot foto\'s, media en lêers op jou toestel"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"oudio op te neem"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan tik, swiep, knyp en ander gebare uitvoer."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Vingerafdrukgebare"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan gebare vasvang wat op die toestel se vingerafdruksensor uitgevoer word."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktiveer of verander statusbalk"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"wees die statusbalk"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Verhoog volume bo aanbevole vlak?\n\nOm lang tydperke teen hoë volume te luister, kan jou gehoor beskadig."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gebruik toeganklikheidkortpad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Wanneer die kortpad aan is, sal \'n toeganklikheidkenmerk begin word as albei volumeknoppies 3 sekondes lank gedruk word.\n\n Bestaande toeganklikheidkenmerk:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Jy kan die kenmerk in Instellings &gt; Toeganklikheid verander."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Maak leeg"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Wysig kortpaaie"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Kanselleer"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Skakel kortpad af"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Skakel werkprofiel aan?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Jou werkprogramme, kennisgewings, data en ander werkprofielkenmerke sal aangeskakel word"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Skakel aan"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Hierdie program is vir \'n ouer weergawe van Android gebou en sal dalk nie behoorlik werk nie. Probeer kyk vir opdaterings, of kontak die ontwikkelaar."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kyk vir opdatering"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Jy het nuwe boodskappe"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery kan afloop voordat dit normaalweg gelaai word"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterybespaarder is geaktiveer om batterylewe te verleng"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterybespaarder"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Batterybespaarder sal nie weer aanskakel voordat battery amper pap is nie"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Battery is tot \'n voldoende vlak gelaai. Batterybespaarder sal nie weer aanskakel voordat battery amper pap is nie"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Foon <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> gelaai"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> gelaai"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Toestel <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> gelaai"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Batterybespaarder is af. Kenmerke is nie meer beperk nie."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Batterybespaarder is afgeskakel. Kenmerke is nie meer beperk nie."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Vouer"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-program"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Lêer"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 9b9dbb0..c92d3b0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"ኤስኤምኤስ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"የኤስኤምኤስ መልዕክቶችን ይላኩና ይመልከቱ"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ማከማቻ"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"ፋይሎች እና ሚዲያ"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"በመሳሪያዎ ላይ ያሉ ፎቶዎችን፣ ማህደረመረጃን እና ፋይሎችን ይድረሱ"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ማይክሮፎን"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ኦዲዮ ይቅዱ"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"መታ ማድረግ፣ ማንሸራተት፣ መቆንጠጥ እና ሌሎች የጣት ምልክቶችን ማከናወን ይችላል።"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"የጣት አሻራ ምልክቶች"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"በመሣሪያው የጣት አሻራ ዳሳሽ ላይ የተከናወኑ የጣት ምልክቶችን መያዝ ይችላል።"</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ቅጽበታዊ ገጽ እይታን ያነሳል"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"የማሳያው ቅጽበታዊ ገጽ እይታን ማንሳት ይችላል።"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"የሁኔታ አሞሌ መሆን"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ድምጹ ከሚመከረው መጠን በላይ ከፍ ይበል?\n\nበከፍተኛ ድምጽ ለረጅም ጊዜ ማዳመጥ ጆሮዎን ሊጎዳው ይችላል።"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"የተደራሽነት አቋራጭ ጥቅም ላይ ይዋል?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"አቋራጩ ሲበራ ሁለቱንም የድምፅ አዝራሮች ለ3 ሰከንዶች ተጭኖ መቆየት የተደራሽነት ባህሪን ያስጀምረዋል።\n\n አሁን ያለ የተደራሽነት ባህሪ፦\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ባህሪውን በቅንብሮች &gt; ተደራሽነት ውስጥ ሊለውጡት ይችላሉ።"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ባዶ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"አቋራጮችን አርትዕ ያድርጉ"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ይቅር"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"አቋራጩን አጥፋ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"አቋራጭ ይጠቀሙ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ተቃራኒ ቀለም"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"የስራ መገለጫ ይብራ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"የእርስዎ የስራ መተግበሪያዎች፣ ማሳወቂያዎች፣ ውሂብ እና ሌሎች የስራ መገለጫ ባህሪያት ይበራሉ"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"አብራ"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"መተግበሪያ አይገኝም"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> አሁን አይገኝም።"</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ይህ መተግበሪያ ለቆየ የAndroid ስሪት ነው የተገነባው፣ እና በአግባቡ ላይሰራ ይችላል። ዝማኔዎች ካሉ ለመመልከት ይሞክሩ፣ ወይም ደግሞ ገንቢውን ያነጋግሩ።"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ዝማኔ ካለ አረጋግጥ"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"አዲስ መልዕክቶች አለዎት"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ባትሪ ከተለመደው ኃይል መሙላት በፊት ሊያልቅ ይችላል"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"የባትሪ ቆጣቢ የባትሪ ዕድሜን ለማራዘም ገብሯል።"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ባትሪ ቆጣቢ"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ባትሪ ቆጣቢ ባትሪ እንደገና ዝቅ እስከሚል ድረስ ዳግም አይገብርም።"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ባትሪ በቂ ወደ ሆነ ደረጃ ኃይል ተሞልቷል። የባትሪ ቆጣቢ ባቲትው እንደገና ዝቅ እስከሚል ድረስ ዳግም አይገብርም።"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ስልክ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ኃይል ተሞልቷል"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ጡባዊ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ኃይል ተሞልቷል"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"መሣሪያ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ኃይል ተሞልቷል"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"የባትሪ ኃይል ቆጣቢ ጠፍቷል። ባህሪያት ከእንግዲህ የተገደቡ አይደሉም።"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"የባትሪ ቆጣቢ ጠፍቷል። ባህሪያት ከእንግዲህ የተገደቡ አይደሉም።"</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"የባትሪ ቆጣቢ ጠፍቷል"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"ስልክ በቂ የባትሪ ኃይል አለው። ባህሪያት ከእንግዲህ የተገደቡ አይደሉም።"</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"ጡባዊ በቂ የባትሪ ኃይል አለው። ባህሪያት ከእንግዲህ የተገደቡ አይደሉም።"</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"መሣሪያ በቂ የባትሪ ኃይል የለውም። ባህሪያት ከእንግዲህ የተገደቡ አይደሉም።"</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"አቃፊ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"የAndroid መተግበሪያ"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ፋይል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 68708d35..1a6bbd8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -299,7 +299,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"الوصول تقويمك"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏إرسال رسائل قصيرة SMS وعرضها"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"التخزين"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"الوصول إلى الصور والوسائط والملفات على جهازك"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"الميكروفون"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"تسجيل الصوت"</string>
@@ -322,9 +323,13 @@
     <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"التحكم في تكبير الشاشة"</string>
     <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"يمكنك التحكّم في مستوى تكبير/تصغير الشاشة وتحديد الموضع."</string>
     <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"تنفيذ إيماءات"</string>
-    <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"يمكن النقر والتمرير بسرعة والتصغير وتنفيذ إيماءات أخرى."</string>
+    <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"يمكن النقر والتمرير بسرعة والتصغير أو التكبير بإصبعين وتنفيذ إيماءات أخرى."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"إيماءات بصمات الإصبع"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"يمكن أن تلتقط الإيماءات التي تم تنفيذها على جهاز استشعار بصمات الإصبع في الجهاز."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"إيقاف شريط الحالة أو تعديله"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"للسماح للتطبيق بإيقاف شريط الحالة أو إضافة رموز نظام وإزالتها."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"العمل كشريط للحالة"</string>
@@ -658,13 +663,13 @@
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"للسماح للمالك ببدء استخدام الإذن لأحد التطبيقات. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"للتحكم في الطول والأحرف المسموح بها في كلمات المرور وأرقام التعريف الشخصي في قفل الشاشة."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"مراقبة محاولات إلغاء قفل الشاشة"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"لمراقبة عدد مرات كتابة كلمات المرور غير الصحيحة عند إلغاء تأمين الشاشة وتأمين الجهاز اللوحي أو مسح جميع بياناته في حالة كتابة الكثير من كلمات المرور غير الصحيحة."</string>
-    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"‏يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند إلغاء قفل الشاشة، وقفل جهاز Android TV أو محو جميع بيانات جهاز Android TV إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
-    <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند إلغاء تأمين الشاشة، وتأمين الهاتف ومحو جميع بياناته إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند إلغاء تأمين الشاشة، وتأمين الجهاز اللوحي ومحو جميع بيانات هذا المستخدم إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"‏يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند إلغاء قفل الشاشة، وقفل جهاز Android TV أو محو جميع بيانات هذا المستخدم إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند إلغاء تأمين الشاشة، وتأمين الهاتف ومحو جميع بيانات هذا المستخدم إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"مراقبة محاولات فتح قفل الشاشة"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"لمراقبة عدد مرات كتابة كلمات المرور غير الصحيحة عند فتح قفل الشاشة وتأمين الجهاز اللوحي أو مسح جميع بياناته في حالة كتابة الكثير من كلمات المرور غير الصحيحة."</string>
+    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"‏يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند فتح قفل الشاشة، وقفل جهاز Android TV أو محو جميع بيانات جهاز Android TV إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند فتح قفل الشاشة، وتأمين الهاتف ومحو جميع بياناته إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند فتح قفل الشاشة، وتأمين الجهاز اللوحي ومحو جميع بيانات هذا المستخدم إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"‏يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند فتح قفل الشاشة، وقفل جهاز Android TV أو محو جميع بيانات هذا المستخدم إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"يمكنك مراقبة عدد كلمات المرور غير الصحيحة التي تمت كتابتها عند فتح قفل الشاشة، وتأمين الهاتف ومحو جميع بيانات هذا المستخدم إذا تمت كتابة عدد أكبر من اللازم من كلمات المرور غير الصحيحة."</string>
     <string name="policylab_resetPassword" msgid="214556238645096520">"تغيير قفل الشاشة"</string>
     <string name="policydesc_resetPassword" msgid="4626419138439341851">"إمكانية تغيير قفل الشاشة"</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"قفل الشاشة"</string>
@@ -821,7 +826,7 @@
     <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"صحيح!"</string>
     <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"أعد المحاولة"</string>
     <string name="lockscreen_password_wrong" msgid="8605355913868947490">"أعد المحاولة"</string>
-    <string name="lockscreen_storage_locked" msgid="634993789186443380">"إلغاء قفل جميع الميزات والبيانات"</string>
+    <string name="lockscreen_storage_locked" msgid="634993789186443380">"فتح قفل جميع الميزات والبيانات"</string>
     <string name="faceunlock_multiple_failures" msgid="681991538434031708">"تم تجاوز الحد الأقصى لعدد محاولات تأمين الجهاز بالوجه"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"‏ليست هناك شريحة SIM"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"‏ليس هناك شريحة SIM في الجهاز اللوحي."</string>
@@ -843,22 +848,22 @@
     <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"‏شريحة SIM مؤمّنة بكود PUK."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"راجع دليل المستخدم أو اتصل بخدمة العملاء."</string>
     <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"‏شريحة SIM مؤمّنة."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"‏جارٍ إلغاء تأمين شريحة SIM…"</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"‏جارٍ فتح قفل شريحة SIM…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"لقد رسمت نقش فتح القفل بطريقة غير صحيحة <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة.\n\nيُرجى إعادة المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"لقد كتبت كلمة المرور <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة بشكل غير صحيح. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"‏لقد كتبت رمز PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة بشكل غير صحيح. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"‏لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"‏لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء<xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة أخرى غير ناجحة، ستُطالب بإلغاء قفل جهاز Android TV باستخدام معلومات تسجيل الدخول إلى Google.\n\n يُرجى إعادة المحاولة بعد <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"‏لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
-    <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">"‏لقد حاولت إلغاء قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <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>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"لقد حاولت إلغاء تأمين الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الجهاز اللوحي إلى الإعدادات الأساسية."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"‏لقد حاولت إلغاء قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم الآن إعادة ضبط جهاز Android TV على الإعداد التلقائي للمصنع."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"لقد حاولت إلغاء تأمين الهاتف <xliff:g id="NUMBER">%d</xliff:g> من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الهاتف إلى الإعدادات الأساسية."</string>
+    <string name="lockscreen_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">"‏لقد حاولت فتح قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <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>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"لقد حاولت فتح قفل الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الجهاز اللوحي إلى الإعدادات الأساسية."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"‏لقد حاولت فتح قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم الآن إعادة ضبط جهاز Android TV على الإعداد التلقائي للمصنع."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"لقد حاولت فتح قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الهاتف إلى الإعدادات الأساسية."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%d</xliff:g> ثانية."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"هل نسيت النمط؟"</string>
-    <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"إلغاء تأمين الحساب"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"فتح قفل الحساب"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"محاولات النقش كثيرة جدًا"</string>
     <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"‏لإلغاء التأمين، سجّل الدخول بحسابك في Google."</string>
     <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"اسم المستخدم (البريد إلكتروني)"</string>
@@ -867,7 +872,7 @@
     <string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"اسم المستخدم غير صحيح أو كلمة المرور غير صحيحة."</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"‏هل نسيت اسم المستخدم أو كلمة المرور؟\nانتقل إلى "<b>"google.com/accounts/recovery"</b></string>
     <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"جارٍ التحقق..."</string>
-    <string name="lockscreen_unlock_label" msgid="4648257878373307582">"إلغاء تأمين"</string>
+    <string name="lockscreen_unlock_label" msgid="4648257878373307582">"فتح قفل"</string>
     <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"تشغيل الصوت"</string>
     <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"الصوت متوقف"</string>
     <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"بدأ النمط"</string>
@@ -879,8 +884,8 @@
     <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"‏%1$s. الأداة %2$d من %3$d."</string>
     <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"إضافة أداة."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"فارغة"</string>
-    <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"تم توسيع منطقة إلغاء القفل."</string>
-    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"تم تصغير منطقة إلغاء القفل."</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"تم توسيع منطقة فتح القفل."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"تم تصغير منطقة فتح القفل."</string>
     <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"أداة <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
     <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"محدد المستخدم"</string>
     <string name="keyguard_accessibility_status" msgid="6792745049712397237">"الحالة"</string>
@@ -889,14 +894,14 @@
     <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"بدأت إعادة ترتيب الأدوات."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"انتهت إعادة ترتيب الأدوات."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"تم حذف أداة <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"توسيع منطقة إلغاء القفل."</string>
-    <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"إلغاء القفل باستخدام التمرير."</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"إلغاء القفل باستخدام النقش."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"توسيع منطقة فتح القفل."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"فتح القفل باستخدام التمرير."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"فتح القفل باستخدام النقش."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="632407612842329815">"تأمين الجهاز بالوجه."</string>
-    <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"‏إلغاء القفل باستخدام رمز PIN."</string>
-    <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"‏إلغاء قفل رقم التعريف الشخصي لشريحة SIM."</string>
-    <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"‏إلغاء قفل مفتاح PUK لشريحة SIM."</string>
-    <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"إلغاء القفل باستخدام كلمة المرور."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"‏فتح القفل باستخدام رمز PIN."</string>
+    <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"‏فتح قفل رقم التعريف الشخصي لشريحة SIM."</string>
+    <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"‏فتح قفل مفتاح PUK لشريحة SIM."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"فتح القفل باستخدام كلمة المرور."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"منطقة النقش."</string>
     <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"منطقة التمرير."</string>
     <string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string>
@@ -1388,7 +1393,7 @@
     <string name="adb_active_notification_message" msgid="5617264033476778211">"‏انقر لإيقاف تصحيح أخطاء الجهاز عبر USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"‏اختيار إيقاف تصحيح أخطاء USB."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
-    <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"."</string>
+    <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"."</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"وحدة التحكّم التسلسلية مفعّلة"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string>
     <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"‏السوائل والشوائب في منفذ USB"</string>
@@ -1398,7 +1403,7 @@
     <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"جارٍ الحصول على تقرير الخطأ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"هل تريد مشاركة تقرير الخطأ؟"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"جارٍ مشاركة تقرير الخطأ…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"طلب المشرف الحصول على تقرير خطأ للمساعدة في تحرِّي مشكلة هذا الجهاز وإصلاحها؛ ويمكن أن تتم مشاركة التطبيقات والبيانات."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"طلب المشرف الحصول على تقرير خطأ للمساعدة في تحديد مشكلة هذا الجهاز وحلّها؛ ويمكن أن تتم مشاركة التطبيقات والبيانات."</string>
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"مشاركة"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"رفض"</string>
     <string name="select_input_method" msgid="3971267998568587025">"اختيار أسلوب الإدخال"</string>
@@ -1464,7 +1469,7 @@
     <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"للسماح لتطبيق ما بطلب حذف الحِزم."</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"طلب تجاهل تحسينات البطارية"</string>
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"للسماح للتطبيق بطلب الإذن لتجاهل تحسينات البطارية في هذا التطبيق."</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"اضغط مرتين للتحكم في التكبير/التصغير"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"اضغط مرتين للتحكم في التكبير أو التصغير"</string>
     <string name="gadget_host_error_inflating" msgid="2449961590495198720">"تعذرت إضافة أداة."</string>
     <string name="ime_action_go" msgid="5536744546326495436">"تنفيذ"</string>
     <string name="ime_action_search" msgid="4501435960587287668">"بحث"</string>
@@ -1667,7 +1672,7 @@
     <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"‏شريحة SIM غير مفعّلة الآن. أدخل رمز PUK للمتابعة. اتصل بمشغل شبكة الجوال للاطلاع على التفاصيل."</string>
     <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"‏إدخال رمز رمز PIN المراد"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"‏تأكيد رمز رمز PIN المراد"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"‏جارٍ إلغاء تأمين شريحة SIM…"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"‏جارٍ فتح قفل شريحة SIM…"</string>
     <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"‏رمز PIN غير صحيح."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"اكتب  رقم التعريف الشخصي المكون من ٤ إلى ٨ أرقام."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"‏يجب أن يتكون رمز PUK من ۸ أرقام."</string>
@@ -1684,12 +1689,12 @@
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"‏لقد كتبت رمز PIN بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"لقد رسمت نقش فتح القفل بطريقة غير صحيحة <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"لقد حاولت إلغاء تأمين الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"‏لقد حاولت إلغاء قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة أخرى غير ناجحة، ستتم إعادة ضبط جهاز Android TV على الإعداد التلقائي للمصنع وسيتم فقدان جميع بيانات المستخدمين."</string>
-    <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">"‏لقد حاولت إلغاء قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم الآن إعادة ضبط جهاز Android TV على الإعداد التلقائي للمصنع."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. سيتم الآن إعادة تعيين الهاتف على الإعدادات الأساسية."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"لقد حاولت فتح قفل الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الأساسية وسيتم فقد جميع بيانات المستخدم."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"‏لقد حاولت فتح قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة أخرى غير ناجحة، ستتم إعادة ضبط جهاز Android TV على الإعداد التلقائي للمصنع وسيتم فقدان جميع بيانات المستخدمين."</string>
+    <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">"‏لقد حاولت فتح قفل جهاز Android TV بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم الآن إعادة ضبط جهاز Android TV على الإعداد التلقائي للمصنع."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"لقد حاولت فتح قفل الهاتف بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. سيتم الآن إعادة تعيين الهاتف على الإعدادات الأساسية."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"‏لقد رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة أخرى غير ناجحة، ستُطالب بإلغاء قفل جهاز Android TV باستخدام حساب بريد إلكتروني.\n\n يُرجى إعادة المحاولة بعد <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
     <string name="kg_failed_attempts_almost_at_login" product="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>
@@ -1698,6 +1703,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"عند تشغيل الاختصار، يؤدي الضغط على زرّي مستوى الصوت لمدة 3 ثوانٍ إلى تفعيل ميزة \"سهولة الاستخدام\".\n\n ميزة \"سهولة الاستخدام\" الحالية:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n يمكنك تغيير الميزة من \"الإعدادات\" &gt; \"سهولة الاستخدام\"."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"فارغ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"تعديل الاختصارات"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"إلغاء"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"إيقاف الاختصار"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استخدام الاختصار"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"عكس الألوان"</string>
@@ -1973,6 +1981,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"تفعيل الملف الشخصي للعمل؟"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"سيتم تفعيل تطبيقات العمل التي تستخدمها والإشعارات والبيانات وغيرها من ميزات الملف الشخصي للعمل"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"تشغيل"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏تمّ إنشاء هذا التطبيق لإصدار قديم من Android وقد لا يعمل بشكل صحيح. جرِّب البحث عن تحديثات أو الاتصال بمطوّر البرامج."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"البحث عن تحديث"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"لديك رسائل جديدة"</string>
@@ -2035,7 +2047,7 @@
     <string name="autofill_save_notnow" msgid="2853932672029024195">"ليس الآن"</string>
     <string name="autofill_save_never" msgid="6821841919831402526">"أبدًا"</string>
     <string name="autofill_update_yes" msgid="4608662968996874445">"تعديل"</string>
-    <string name="autofill_continue_yes" msgid="7914985605534510385">"متابعة"</string>
+    <string name="autofill_continue_yes" msgid="7914985605534510385">"مواصلة"</string>
     <string name="autofill_save_type_password" msgid="5624528786144539944">"كلمة مرور"</string>
     <string name="autofill_save_type_address" msgid="3111006395818252885">"عنوان"</string>
     <string name="autofill_save_type_credit_card" msgid="3583795235862046693">"بطاقة ائتمان"</string>
@@ -2087,13 +2099,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"قد تنفد طاقة البطارية قبل الشحن المعتاد"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"تم تفعيل \"توفير شحن البطارية\" لإطالة عمرها."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"توفير شحن البطارية"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"لن يتم تفعيل ميزة \"توفير شحن البطارية\" مرة أخرى حتى تنخفض طاقة البطارية مرة أخرى."</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"وصل شحن البطارية إلى مستوى كافٍ. لن يتم تفعيل ميزة \"توفير شحن البطارية\" حتى تنخفض طاقة البطارية مرة أخرى."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"وصل مستوى شحن الهاتف إلى <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"وصل مستوى شحن الجهاز اللوحي إلى <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"وصل مستوى شحن الجهاز إلى <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"توفير شحن البطارية لا يعمل. لم تعُد الميزات مقيّدة."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"تم تفعيل \"توفير شحن البطارية\". لم تعُد الميزات مقيّدة."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"مجلّد"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"‏تطبيق Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ملف"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 149ac6b..faa99a2 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপোনাৰ কেলেণ্ডাৰ ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"এছএমএছ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"এছএমএছ বার্তা পঠিয়াব আৰু চাব পাৰে"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"সঞ্চয়াগাৰ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"আপোনাৰ ডিভাইচৰ ফট\', মিডিয়া আৰু ফাইলসমূহ ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"মাইক্ৰ\'ফ\'ন"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"অডিঅ\' ৰেকর্ড কৰিব পাৰে"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"টেপ কৰা, ছোৱাইপ কৰা, পিঞ্চ কৰা আৰু আঙুলিৰ স্পৰ্শেৰে নিৰ্দেশ কৰা অন্যান্য কাৰ্যসমূহ কৰিব পাৰে।"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ফিংগাৰপ্ৰিণ্ট নিৰ্দেশ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ডিভাইচটোৰ ফিংগাৰপ্ৰিণ্ট ছেন্সৰত দিয়া নিৰ্দেশ বুজিব পাৰে।"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"স্থিতি দণ্ড অক্ষম কৰক বা সলনি কৰক"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"স্থিতি দণ্ড অক্ষম কৰিবলৈ বা ছিষ্টেম আইকন আঁতৰাবলৈ এপটোক অনুমতি দিয়ে।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"স্থিতি দণ্ড হ\'ব পাৰে"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"অনুমোদিত স্তৰতকৈ ওপৰলৈ ভলিউম বঢ়াব নেকি?\n\nদীৰ্ঘ সময়ৰ বাবে উচ্চ ভলিউমত শুনাৰ ফলত শ্ৰৱণ ক্ষমতাৰ ক্ষতি হ\'ব পাৰে।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাট ব্যৱহাৰ কৰেনে?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"শ্বৰ্টকাট অন হৈ থকাৰ সময়ত দুয়োটা ভলিউম বুটামত ৩ ছেকেণ্ডৰ বাবে ছাপ দি থাকিলে দিব্যাংগসকলৰ বাবে থকা সুবিধা এটা আৰম্ভ হ\'ব। \n\n চলিত দিব্যাংগসকলৰ সুবিধা:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n আপুনি এই সুবিধাটো ছেটিংসমূহ &gt; দিব্যাংগসকলৰ বাবে সুবিধা-লৈ গৈ সলনি কৰিব পাৰে।"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"খালী কৰক"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"শ্বৰ্টকাটসমূহ সম্পাদনা কৰক"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"বাতিল কৰক"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"শ্বৰ্টকাট অফ কৰক"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শ্বৰ্টকাট ব্যৱহাৰ কৰক"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"কৰ্মস্থানৰ প্ৰ\'ফাইল অন কৰিবনে?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"আপোনাৰ কৰ্মস্থানৰ এপসমূহ, জাননীসমূহ, ডেটা আৰু কৰ্মস্থানৰ প্ৰ\'ফাইলৰ অইন সুবিধাসমূহ অন কৰা হ\'ব"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"অন কৰক"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল, আৰু ই বিচৰাধৰণে কাম নকৰিবও পাৰে। ইয়াৰ আপডে’ট আছে নেকি চাওক, বা বিকাশকৰ্তাৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডে’ট আছে নেকি চাওক"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"আপুনি নতুন বার্তা লাভ কৰিছে"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"চ্চাৰ্জ কৰাৰ সচৰাচৰ সময়ৰ আগতেই বেটাৰি শেষ হ’ব পাৰে"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"বেটাৰিৰ খৰচ কমাবলৈ বেটাৰি সঞ্চয়কাৰী অন কৰা হৈছে"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"বেটাৰি সঞ্চয়কাৰী"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"বেটাৰিৰ চাৰ্জ নকমালৈকে বেটাৰি সঞ্চয়কাৰী পুনৰ সক্ৰিয় নহয়"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"বেটাৰি পৰ্যাপ্ত পৰিমাণে চাৰ্জ হৈছে। বেটাৰিৰ চাৰ্জ নকমালৈকে বেটাৰি সঞ্চয়কাৰী পুনৰ সক্ৰিয় নহয়।"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ফ’ন <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> চাৰ্জ হ’ল"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"টেবলেট <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> চাৰ্জ হ’ল"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ডিভাইচটো <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> চাৰ্জ হ’ল"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"বেটাৰি সঞ্চয়কাৰী অফ আছে। সুবিধাবোৰ ব্যৱহাৰ কৰাত এতিয়া বাধা নাই।"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"বেটাৰি সঞ্চয়কাৰী অফ কৰা হ’ল। সুবিধাবোৰ ব্যৱহাৰ কৰাত এতিয়া বাধা নাই।"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ফ’ল্ডাৰ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android এপ্লিকেশ্বন"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ফাইল"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 829b8a0..d97b73f 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"təqvimə daxil olun"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"göndərin və SMS mesajlarına baxın"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Yaddaş"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"cihazınızda foto, media və fayllara daxil olun"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"səsi qeydə alın"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Digər jestlərə tıklaya, sürüşdürə və əməliyyat apara bilərsiniz."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Barmaq izi işarələri"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Cihazların barmaq izi sensorunda olan işarələri əldə edə bilər."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"status panelini deaktivləşdir və ya dəyişdir"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"status paneli edin"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Səsin həcmi tövsiyə olunan səviyyədən artıq olsun?\n\nYüksək səsi uzun zaman dinləmək eşitmə qabiliyyətinizə zərər vura bilər."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Əlçatımlılıq Qısayolu istifadə edilsin?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Qısayol aktiv olduqda hər iki səs düyməsinə 3 saniyə basıb saxlamaqla əlçatımlılıq funksiyası işə başlayacaq.\n\n Cari əlçatımlılıq funksiyası:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funksiyanı Ayarlar və Əçatımlılıq bölməsində dəyişə bilərsiniz."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Boşaldın"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Qısayolları redaktə edin"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Ləğv edin"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Qısayolu Deaktiv edin"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Qısayol İstifadə edin"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Rəng İnversiyası"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"İş profili aktiv edilsin?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"İş tətbiqləri, bildirişləri, data və digər iş profili funksiyaları aktiv ediləcək"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivləşdirin"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu tətbiq köhnə Android versiyası üçün hazırlanıb və düzgün işləməyə bilər. Güncəlləməni yoxlayın və ya developer ilə əlaqə saxlayın."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncəlləməni yoxlayın"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batareya həmişəki vaxtdan əvvəl bitə bilər"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Enerjiyə Qənaət rejimi batareya istifadəsinin müddətini artırmaq üçün aktiv edilir"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Enerjiyə qənaət"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Enerjiyə qənaət batareya az olana qədər aktiv edilməyəcək"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batareya kifayət qədər dolub. Enerjiyə qənaət batareya az olana qədər aktiv edilməyəcək."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Batareya <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> dolub"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Batareya <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> dolub"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Batareya <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> dolub"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Enerjiyə qənaət deaktivdir. Funksiyalar artıq məhdud deyil."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Enerjiyə qənaət deaktivdir. Funksiyalar artıq məhdud deyil."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Qovluq"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android tətbiqi"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fayl"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 7909872..c37e2b4 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -290,7 +290,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupi kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Memorijski prostor"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Datoteke i mediji"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"pristupa slikama, medijima i datotekama na uređaju"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
@@ -316,6 +316,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Pokreti za otisak prsta"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može da registruje pokrete na senzoru za otisak prsta na uređaju."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Napravi snimak ekrana"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može da napravi snimak ekrana."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmena statusne trake"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcionisanje kao statusna traka"</string>
@@ -1632,6 +1634,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li da koristite prečicu za pristupačnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti.\n\n Aktuelna funkcija pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Možete da promenite funkciju u odeljku Podešavanja &gt; Pristupačnost."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Prazno"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Izmenite prečice"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Otkaži"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
@@ -1877,6 +1882,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Da uključimo profil za Work?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Uključiće se poslovne aplikacije, obaveštenja, podaci i druge funkcije profila za Work"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je napravljena za stariju verziju Android-a, pa možda neće raditi ispravno. Potražite ažuriranja ili kontaktirajte programera."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Potraži ažuriranje"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
@@ -1988,13 +1995,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija će se možda isprazniti pre uobičajenog punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžilo trajanje baterije"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ušteda baterije"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Ušteda baterije se neće ponovo aktivirati dok baterija ne bude skoro prazna"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Baterija je napunjena do zadovoljavajućeg nivoa. Ušteda baterije se neće ponovo aktivirati dok baterija ne bude skoro prazna."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Uređaj je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Ušteda baterije je isključena. Funkcije više nisu ograničene."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Ušteda baterije je isključena. Funkcije više nisu ograničene."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ušteda baterije je isključena"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterija telefona je dovoljno napunjena. Funkcije više nisu ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Baterija tableta je dovoljno napunjena. Funkcije više nisu ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Baterija uređaja je dovoljno napunjena. Funkcije više nisu ograničene."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Direktorijum"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android aplikacija"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Datoteka"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 306934b..855ce25 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"атрымліваць доступ да вашага календара"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"адпраўляць і праглядаць SMS-паведамленні"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Сховішча"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"атрымліваць доступ да фатаграфій, медыяфайлаў і файлаў на вашай прыладзе"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Мікрафон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"запісваць аўдыя"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Можна кранаць, праводзіць пальцам, маштабаваць шчыпком, а таксама выконваць іншыя жэсты."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Жэсты на сканеры адбіткаў пальцаў"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Можа распазнаваць жэсты на сканеры адбіткаў пальцаў прылады."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"адключаць ці змяняць радок стану"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"быць панэллю стану"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Калі камбінацыя хуткага доступу ўключана, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб уключыць функцыю спецыяльных магчымасцей.\n\n Бягучая функцыя спецыяльных магчымасцей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Вы можаце змяніць гэту функцыю ў меню \"Налады &gt; Спецыяльныя магчымасці\"."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Пуста"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Змяніць ярлыкі"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Скасаваць"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Дэактываваць камбінацыю хуткага доступу"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колеру"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Уключыць працоўны профіль?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Будуць уключаны вашы рабочыя праграмы, апавяшчэнні, даныя і іншыя функцыі працоўнага профілю"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Уключыць"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Гэта праграма была створана для больш старой версіі Android і можа не працаваць належным чынам. Праверце наяўнасць абнаўленняў або звярніцеся да распрацоўшчыка."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць на наяўнасць абнаўленняў"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"У вас ёсць новыя паведамленні"</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Акумулятар можа разрадзіцца хутчэй, чым прыйдзе час звычайнай зарадкі"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Каб павялічыць тэрмін работы акумулятара, уключаны рэжым эканоміі зараду"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Эканомія зараду"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Рэжым эканоміі зараду ўключыцца зноў, калі ў акумулятара будзе нізкі зарад"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Акумулятар зараджаны да дастатковага ўзроўню. Рэжым эканоміі зараду ўключыцца зноў, калі ў акумулятара будзе нізкі зарад."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Узровень зараду тэлефона: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Узровень зараду планшэта: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Узровень зараду прылады: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Рэжым эканоміі зараду выключаны. Функцыі больш не абмежаваны."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Рэжым эканоміі зараду выключаны. Функцыі больш не абмежаваны."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Праграма Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index dfa4a2f..40e20d3 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"има достъп до календара ви"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"да изпраща и преглежда SMS съобщения"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Хранилище"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Файлове и мултимедия"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"да има достъп до снимките, мултимедията и файловете на устройството ви"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"записва звук"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Можете да докосвате, да прекарвате пръст, да събирате пръсти и да извършвате други жестове."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Жестове за отпечатък"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да улавя жестовете, извършени върху сензора за отпечатъци на устройството."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Създаване на екранна снимка"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да създава екранни снимки."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"деактивиране или промяна на лентата на състоянието"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Разрешава на приложението да деактивира лентата на състоянието или да добавя и премахва системни икони."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"изпълняване на ролята на лента на състоянието"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да се увеличи ли силата на звука над препоръчителното ниво?\n\nПродължителното слушане при висока сила на звука може да увреди слуха ви."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Искате ли да използвате пряк път към функцията за достъпност?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Когато прекият път е включен, можете да стартирате дадена функция за достъпност, като натиснете двата бутона за промяна на силата на звука и ги задържите 3 секунди.\n\n Текущата функция за достъпност е:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Можете да промените функцията от „Настройки“ &gt; „Достъпност“."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Празно"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Редактиране на преките пътища"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Отказ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Изключване на прекия път"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Използване на пряк път"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инвертиране на цветовете"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Вкл. на служ. потр. профил?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Служебните ви приложения, известия и данни, както и другите функции на служебния потребителски профил ще бъдат включени"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Включване"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Приложението не е достъпно"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"В момента няма достъп до <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Това приложение бе създадено за по-стара версия на Android и може да не работи правилно. Опитайте да проверите за актуализации или се свържете с програмиста."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за актуализация"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови съобщения"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерията може да се изтощи преди обичайното зареждане"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Режимът за запазване на батерията е активиран с цел удължаване на живота на батерията"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим за запазване на батерията"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Режимът за запазване на батерията няма да се активира отново, докато тя пак не се изтощи"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батерията е достатъчно заредена. Режимът за запазването й няма да се активира отново, докато тя пак не се изтощи."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефонът е зареден на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Таблетът е зареден на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Устройството е заредено на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Режимът за запазване на батерията е изключен. Функциите вече не са ограничени."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Режимът за запазване на батерията е изключен. Функциите вече не са ограничени."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Режимът за запазване на батерията е изключен"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Батерията на телефона има достатъчно заряд. Функциите вече не са ограничени."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Батерията на таблета има достатъчно заряд. Функциите вече не са ограничени."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Батерията на устройството има достатъчно заряд. Функциите вече не са ограничени."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Приложение за Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 150fc7d..3164bb6 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"এসএমএসগুলি পাঠাতে এবং দেখতে"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"স্টোরেজ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"আপনার ডিভাইসে ফটো, মিডিয়া এবং ফাইলগুলিতে অ্যাক্সেস"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"মাইক্রোফোন"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"অডিও রেকর্ড"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"আলতো চাপ দেওয়া, সোয়াইপ, পিঞ্চ করা এবং অন্যান্য ইঙ্গিতের কাজগুলি সম্পাদন করতে পারবেন৷"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"আঙ্গুলের ছাপ সেন্সরের উপর করা জেসচার"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ডিভাইসের আঙ্গুলের ছাপের সেন্সরের উপরে ইঙ্গিত করলে বুঝতে পারে।"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"স্ট্যাটাস বার নিষ্ক্রিয় অথবা সংশোধন করে"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"অ্যাপ্লিকেশনকে স্ট্যাটাস বার অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"স্থিতি দন্ডে থাকুন"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"প্রস্তাবিত স্তরের চেয়ে বেশি উঁচুতে ভলিউম বাড়াবেন?\n\nউঁচু ভলিউমে বেশি সময় ধরে কিছু শুনলে আপনার শ্রবনশক্তির ক্ষতি হতে পারে।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"অ্যাক্সেসযোগ্যতা শর্টকাট ব্যবহার করবেন?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"শর্টকাটটি চালু থাকলে দুটি ভলিউম বোতাম একসাথে ৩ সেকেন্ড টিপে ধরে রাখলে একটি অ্যাকসেসিবিলিটি বৈশিষ্ট্য চালু হবে।\n\n বর্তমান অ্যাকসেসিবিলিটি বৈশিষ্ট্য:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n আপনি এই বৈশিষ্ট্যটি সেটিংস &gt; অ্যাকসেসিবিলিটিতে গিয়ে পরিবর্তন করতে পারবেন।"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"খালি"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"শর্টকাট এডিট করুন"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"বাতিল করুন"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"শর্টকাট বন্ধ করুন"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শর্টকাট ব্যবহার করুন"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"রঙ উল্টানো"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"কাজের প্রোফাইল চালু করবেন?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"আপনার কাজের অ্যাপ, বিজ্ঞপ্তি, ডেটা এবং কাজের প্রোফাইলের অন্যান্য বৈশিষ্ট্য চালু করা হবে"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"চালু করুন"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"এই অ্যাপটি Android এর একটি পুরনো ভার্সনের জন্য তৈরি করা হয়েছিল, তাই এখানে সেটি ঠিকমতো কাজ নাও করতে পারে। আপডেট পাওয়া যাচ্ছে কিনা দেখুন বা ডেভেলপারের সাথে যোগাযোগ করুন।"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডেট পাওয়া যাচ্ছে কিনা দেখুন"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"আপনার নতুন মেসেজ আছে"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"সাধারণত যখন চার্জ দেন, তার আগে চার্জ শেষ হয়ে যেতে পারে"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ডিভাইস বেশিক্ষণ চালু রাখতে ব্যাটারি সেভার চালু করা হয়েছে"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ব্যাটারি সেভার"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"চার্জ কম না হওয়া পর্যন্ত ব্যাটারি সেভার আবার চালু হবে না"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ব্যাটারি পর্যাপ্ত পরিমাণ চার্জ করা হয়েছে। চার্জ কম না হওয়া পর্যন্ত ব্যাটারি সেভার আবার চালু হবে না।"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ফোনে <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> চার্জ আছে"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ট্যাবলেটে <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> চার্জ আছে"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ডিভাইসে <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> চার্জ আছে"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ব্যাটারি সেভার বন্ধ আছে। ফিচারগুলি আর সীমাবদ্ধ নেই।"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ব্যাটারি সেভার বন্ধ করে দেওয়া হয়েছে। ফিচারগুলি আর সীমাবদ্ধ নেই।"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ফোল্ডার"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android অ্যাপ্লিকেশন"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ফাইল"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 3660824..e0a4886 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -290,7 +290,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupa vašem kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Pohrana"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Fajlovi i mediji"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"pristupa slikama, medijskim fajlovima i fajlovima na vašem uređaju"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
@@ -316,6 +316,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Može dodirivati, prevlačiti, hvatati prstima i praviti druge pokrete."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Pokreti otiska prsta"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Moguće je zabilježiti pokrete na senzoru za otisak prsta uređaja."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Snimanje ekrana"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Moguće je snimiti ekran."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili mijenjanje statusne trake"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji onemogućavanje statusne trake ili dodavanje i uklanjanje sistemskih ikona."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcioniranje u vidu statusne trake"</string>
@@ -1634,6 +1636,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li koristiti Prečicu za pristupačnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kada je prečica uključena, pritiskom na oba dugmeta za podešavanje jačine zvuka u trajanju od 3 sekunde pokrenut će se funkcija za pristupačnost.\n\n Trenutna funkcija za pristupačnost je:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciju možete promijeniti ako odete u Postavke &gt; Pristupačnost."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Prazno"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi prečice"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Otkaži"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
@@ -1879,6 +1884,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Uključiti radni profil?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Uključit će se poslovne aplikacije, obavještenja, podaci i druge funkcije radnog profila"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je pravljena za stariju verziju Androida i možda neće ispravno raditi. Provjerite jesu li dostupna ažuriranja ili kontaktirajte programera."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri je li dostupno ažuriranje"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
@@ -1990,13 +1997,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Moguće je da će se baterija isprazniti prije uobičajenog punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžio vijek trajanja baterije"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ušteda baterije"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Ušteda baterije se neće ponovo aktivirati dok se baterija ponovo ne isprazni"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Baterija je dovoljno napunjena. Ušteda baterije se neće ponovo aktivirati dok se baterija ponovo ne isprazni."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Uređaj je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Ušteda baterije je isključena. Funkcije nisu više ograničene."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Ušteda baterije je isključena. Funkcije nisu više ograničene."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ušteda baterije je isključena"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon se dovoljno napunio. Funkcije nisu više ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet se dovoljno napunio. Funkcije nisu više ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Uređaj se dovoljno napunio. Funkcije nisu više ograničene."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android aplikacija"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fajl"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index b265f66..93a60d8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accedir al calendari"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar i llegir missatges SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Emmagatzematge"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Fitxers i multimèdia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"accedir a fotos, contingut multimèdia i fitxers del dispositiu"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micròfon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar àudio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Permet tocar, lliscar, pinçar i fer altres gestos."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos d\'empremtes dactilars"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Captura gestos realitzats en el sensor d\'empremtes dactilars del dispositiu."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fes una captura de pantalla"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pots fer una captura de la pantalla."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra d\'estat"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparèixer a la barra d\'estat"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vols apujar el volum per sobre del nivell recomanat?\n\nSi escoltes música a un volum alt durant períodes llargs, pots danyar-te l\'oïda."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vols fer servir la drecera d\'accessibilitat?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Si la drecera està activada, prem els dos botons de volum durant 3 segons, per iniciar una funció d\'accessibilitat.\n\n Funció d\'accessibilitat actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Pots canviar la funció a Configuració &gt; Accessibilitat."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Buida"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edita les dreceres"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel·la"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactiva la drecera"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilitza la drecera"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversió dels colors"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Activar el perfil professional?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"S\'activaran les teves aplicacions per a la feina, les notificacions, les dades i altres funcions del perfil professional"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activa"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Aquesta aplicació es va crear per a una versió antiga d\'Android i pot ser que no funcioni correctament. Prova de cercar actualitzacions o contacta amb el desenvolupador."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca actualitzacions"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Tens missatges nous"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"És possible que la bateria s\'esgoti abans de la càrrega habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"S\'ha activat l\'estalvi de bateria per prolongar-ne la durada"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Estalvi de bateria"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"L\'estalvi de bateria no es tornarà a activar fins que no tornis a tenir poca bateria"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"La bateria ja està suficientment carregada. L\'estalvi de bateria no es tornarà a activar fins que no tornis a tenir poca bateria."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"El telèfon està carregat un <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tauleta carregada un <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"El dispositiu està carregat un <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"L\'estalvi de bateria s\'ha desactivat. Les funcions ja no estan restringides."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"L\'estalvi de bateria s\'ha desactivat. Les funcions ja no estan restringides."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"L\'estalvi de bateria s\'ha desactivat"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"El telèfon té prou bateria. Les funcions ja no estan restringides."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"La tauleta té prou bateria. Les funcions ja no estan restringides."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"El dispositiu té prou bateria. Les funcions ja no estan restringides."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Carpeta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicació d\'Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fitxer"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 806cb7e..81b1ebb 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -293,7 +293,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"přístup ke kalendáři"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"odesílání a zobrazování zpráv SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Úložiště"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Soubory a média"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"přístup k fotkám, médiím a souborům v zařízení"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávání zvuku"</string>
@@ -319,6 +319,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Může provádět gesta klepnutí, přejetí, stažení prstů a další."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gesta otiskem prstu"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dokáže rozpoznat gesta zadaná na snímači otisků prstů."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Pořídit snímek obrazovky"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Může pořídit snímek obrazovky."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"zakázání či změny stavového řádku"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vydávání se za stavový řádek"</string>
@@ -1654,6 +1656,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšit hlasitost nad doporučenou úroveň?\n\nDlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použít zkratku přístupnosti?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Když je tato zkratka zapnutá, můžete funkci přístupnosti spustit tím, že na tři sekundy podržíte obě tlačítka hlasitosti.\n\n Aktuální funkce přístupnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkci můžete změnit v Nastavení &gt; Přístupnost."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Prázdné"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Upravit zkratky"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Zrušit"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vypnout zkratku"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použít zkratku"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string>
@@ -1909,6 +1914,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Zapnout pracovní profil?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Vaše pracovní aplikace, oznámení, data a ostatní funkce pracovního účtu budou zapnuty"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Zapnout"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> v tuto chvíli není k dispozici."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Tato aplikace byla vytvořena pro starší verzi systému Android a nemusí fungovat správně. Zkuste vyhledat aktualizace, případně kontaktujte vývojáře."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Zkontrolovat aktualizace"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové zprávy"</string>
@@ -2021,13 +2028,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterie se možná vybije před obvyklým časem nabití"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Byl aktivován spořič baterie za účelem prodloužení výdrže"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Spořič baterie"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Spořič baterie se znovu aktivuje, až bude stav baterie opět nízký"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Baterie byla nabita na dostatečnou úroveň. Spořič baterie se znovu aktivuje, až bude baterie opět téměř vybitá."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon je nabitý na <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet je nabitý na <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Zařízení je nabito na <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Spořič baterie je vypnutý. Funkce už nejsou omezeny."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Spořič baterie je vypnutý. Funkce už nejsou omezeny."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Spořič baterie je vypnutý"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon je dostatečně nabitý. Funkce už nejsou omezeny."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet je dostatečně nabitý. Funkce už nejsou omezeny."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Zařízení je dostatečně nabité. Funkce už nejsou omezeny."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Složka"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikace pro Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Soubor"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 81449ad..4374b22 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"have adgang til din kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og se sms-beskeder"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Lagerplads"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"få adgang til billeder, medier og filer på din enhed"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"optage lyd"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan trykke, stryge, knibe sammen og udføre andre bevægelser."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingeraftryksbevægelser"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan registrere bevægelser, der foretages på enhedens fingeraftrykslæser."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller redigere statuslinje"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vær statusbjælken"</string>
@@ -358,7 +363,7 @@
     <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Denne app kan vises oven på andre apps"</string>
     <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Denne app kan vises oven på andre apps eller andre dele af skærmen. Dette kan forstyrre den normale brug af appen og ændre visningen af andre apps."</string>
     <string name="permlab_runInBackground" msgid="541863968571682785">"kør i baggrunden"</string>
-    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Denne app kan køre i baggrunden. Dette kan aflade batteriet hurtigere."</string>
+    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Denne app kan køre i baggrunden. Dette kan dræne batteriet hurtigere."</string>
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"brug data i baggrunden"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Denne app kan bruge data i baggrunden. Dette kan øge dataforbruget."</string>
     <string name="permlab_persistentActivity" msgid="464970041740567970">"sørge for, at appen altid kører"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du skrue højere op end det anbefalede lydstyrkeniveau?\n\nDu kan skade hørelsen ved at lytte til meget høj musik over længere tid."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruge genvejen til Hjælpefunktioner?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Når genvejen er slået til, kan du starte en hjælpefunktion ved at trykke på begge lydstyrkeknapper i tre sekunder.\n\n Nuværende hjælpefunktion:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kan skifte funktion i Indstillinger &gt; Hjælpefunktioner."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Tom"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Rediger genveje"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuller"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Deaktiver genvej"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Brug genvej"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ombytning af farver"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Skal arbejdsprofilen slås til?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Dine arbejdsapps, notifikationer, data og andre funktioner til din arbejdsprofil deaktiveres"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Slå til"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Denne app er lavet til en ældre version af Android og fungerer muligvis ikke korrekt. Prøv at søge efter opdateringer, eller kontakt udvikleren."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Søg efter opdatering"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye beskeder"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Enheden løber muligvis tør for batteri, inden du normalt oplader den"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparefunktion er aktiveret for at forlænge batteritiden"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparefunktion"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Batterisparefunktion genaktiveres ikke, før batteriet er lavt igen"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batteriet er tilstrækkeligt opladet. Batterisparefunktion genaktiveres ikke, før batteriet er lavt igen."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefonen er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> opladet"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Denne tablet er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> opladet"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Enheden er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> opladet"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Batterisparefunktion er slået fra. Funktionerne er ikke længere begrænsede."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Batterisparefunktion er slået fra. Funktionerne er ikke længere begrænsede."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Mappe"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-app"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fil"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 857cdbd..7804e9e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"auf deinen Kalender zugreifen"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS senden und abrufen"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Speicher"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"auf Fotos, Medien und Dateien auf deinem Gerät zugreifen"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"Audio aufnehmen"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Tippen, Wischen, Zusammenziehen und andere Touch-Gesten möglich."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerabdrucksensor-Gesten"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Erfasst Touch-Gesten auf dem Fingerabdrucksensor des Geräts."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"Statusleiste deaktivieren oder ändern"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Statusleiste darstellen"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lautstärke über den Schwellenwert anheben?\n\nWenn du über einen längeren Zeitraum Musik in hoher Lautstärke hörst, kann dies dein Gehör schädigen."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Verknüpfung für Bedienungshilfen verwenden?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Wenn die Verknüpfung aktiviert ist, kannst du die beiden Lautstärketasten drei Sekunden lang gedrückt halten, um eine Bedienungshilfe zu starten.\n\n Aktuelle Bedienungshilfe:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kannst die Bedienungshilfe unter \"Einstellungen\" &gt; \"Bedienungshilfen\" ändern."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Leeren"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Verknüpfungen bearbeiten"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Abbrechen"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Verknüpfung deaktivieren"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Arbeitsprofil aktivieren?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Deine geschäftlichen Apps, Benachrichtigungen, Daten und andere Funktionen des Arbeitsprofils werden aktiviert"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivieren"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Diese App wurde für eine ältere Android-Version entwickelt und funktioniert möglicherweise nicht mehr richtig. Prüfe, ob Updates verfügbar sind oder kontaktiere den Entwickler."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Auf Updates prüfen"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Du hast neue Nachrichten"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Dein Akku könnte vor der gewöhnlichen Ladezeit leer sein"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Energiesparmodus aktiviert, um die Akkulaufzeit zu verlängern"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Energiesparmodus"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Energiesparmodus wird erst bei niedrigem Ladestand wieder aktiviert"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Der Akku ist jetzt ausreichend aufgeladen. Der Energiesparmodus wird erst wieder bei schwachem Ladestand aktiviert."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Ladestand deines Smartphones: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Ladestand Tablet: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Ladestand des Geräts: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Energiesparmodus ist deaktiviert. Es sind keine Funktionen mehr beschränkt."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Energiesparmodus deaktiviert. Es sind keine Funktionen mehr beschränkt."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Ordner"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-App"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Datei"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 817df16b..a5977ee 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"έχει πρόσβαση στο ημερολόγιό σας"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και να διαβάζει μηνύματα SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Αποθηκευτικός χώρος"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Αρχεία και μέσα"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"έχει πρόσβαση στις φωτογραφίες/πολυμέσα/αρχεία στη συσκευή σας"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Μικρόφωνο"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογραφεί"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Επιτρέπει το πάτημα, την ολίσθηση, το πλησίασμα και άλλες κινήσεις."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Κινήσεις δακτυλικών αποτυπωμάτων"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Μπορεί να αναγνωρίσει κινήσεις που εκτελούνται στον αισθητήρα δακτυλικού αποτυπώματος της συσκευής."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Λήψη στιγμιότυπου οθόνης"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Μπορεί να τραβήξει στιγμιότυπο της οθόνης."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"απενεργοποιεί ή να τροποποιεί την γραμμή κατάστασης"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Επιτρέπει στην εφαρμογή να απενεργοποιεί τη γραμμή κατάστασης ή να προσθέτει και να αφαιρεί εικονίδια συστήματος."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ορίζεται ως γραμμή κατάστασης"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Αυξάνετε την ένταση ήχου πάνω από το επίπεδο ασφαλείας;\n\nΑν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Να χρησιμοποιείται η συντόμευση προσβασιμότητας;"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Όταν η συντόμευση είναι ενεργοποιημένη, το πάτημα και των δύο κουμπιών έντασης ήχου για 3 δευτερόλεπτα θα ξεκινήσει μια λειτουργία προσβασιμότητας.\n\n Τρέχουσα λειτουργία προσβασιμότητας:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Μπορείτε να αλλάξετε τη λειτουργία από τις Ρυθμίσεις &gt; Προσβασιμότητα."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Κενό"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Επεξεργασία συντομεύσεων"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Άκυρο"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Απενεργοποίηση συντόμευσης"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Χρήση συντόμευσης"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ενεργοποίηση προφίλ εργασίας;"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Οι εφαρμογές, οι ειδοποιήσεις και τα δεδομένα εργασίας σας, καθώς και άλλες λειτουργίες του προφίλ εργασίας, θα ενεργοποιηθούν"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ενεργοποίηση"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Η εφαρμογή δεν είναι διαθέσιμη"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν είναι διαθέσιμη αυτήν τη στιγμή."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Αυτή η εφαρμογή δημιουργήθηκε για παλαιότερη έκδοση του Android και μπορεί να μην λειτουργεί σωστά. Δοκιμάστε να ελέγξετε εάν υπάρχουν ενημερώσεις ή επικοινωνήστε με τον προγραμματιστή."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Έλεγχος για ενημέρωση"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Έχετε νέα μηνύματα"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Η μπαταρία μπορεί να εξαντληθεί πριν από τη συνηθισμένη φόρτιση"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Η Εξοικονόμηση μπαταρίας ενεργοποιήθηκε για την επέκταση της διάρκειας ζωής της μπαταρίας"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Εξοικονόμηση μπαταρίας"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Η Εξοικονόμηση μπαταρίας δεν θα ενεργοποιηθεί ξανά προτού η στάθμη της μπαταρίας είναι ξανά χαμηλή"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Η μπαταρία φορτίστηκε σε επαρκές επίπεδο. Η Εξοικονόμηση μπαταρίας δεν θα ενεργοποιηθεί ξανά προτού η στάθμη της μπαταρίας είναι ξανά χαμηλή."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Το τηλέφωνο <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> φορτίστηκε"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Επίπεδο φόρτισης tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Η συσκευή <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> φορτίστηκε"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Η Εξοικονόμηση μπαταρίας είναι ανενεργή. Οι λειτουργίες δεν περιορίζονται πλέον."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Η Εξοικονόμηση μπαταρίας απενεργοποιήθηκε. Οι λειτουργίες δεν περιορίζονται πλέον."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Η Εξοικονόμηση μπαταρίας απενεργοποιήθηκε"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Το τηλέφωνο είναι αρκετά φορτισμένο. Οι λειτουργίες δεν περιορίζονται πλέον."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Το tablet είναι αρκετά φορτισμένο. Οι λειτουργίες δεν περιορίζονται πλέον."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Η συσκευή είναι αρκετά φορτισμένη. Οι λειτουργίες δεν περιορίζονται πλέον."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Φάκελος"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Εφαρμογή Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Αρχείο"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 33a8488..da89793 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Storage"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Files and media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"access photos, media and files on your device"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerprint gestures"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Empty"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Battery Saver"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Battery Saver won’t reactivate until battery low again"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Battery has been charged to a sufficient level. Battery Saver won’t reactivate until the battery is low again."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Phone <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Device <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Battery Saver is off. Features no longer restricted."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Battery Saver turned off. Features no longer restricted."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Battery Saver turned off"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Phone has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Device has enough charge. Features no longer restricted."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android application"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index b2ba419..560c4cd 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Storage"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Files and media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"access photos, media and files on your device"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerprint gestures"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Empty"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Battery Saver"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Battery Saver won’t reactivate until battery low again"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Battery has been charged to a sufficient level. Battery Saver won’t reactivate until the battery is low again."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Phone <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Device <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Battery Saver is off. Features no longer restricted."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Battery Saver turned off. Features no longer restricted."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Battery Saver turned off"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Phone has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Device has enough charge. Features no longer restricted."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android application"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 33a8488..da89793 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Storage"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Files and media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"access photos, media and files on your device"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerprint gestures"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Empty"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Battery Saver"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Battery Saver won’t reactivate until battery low again"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Battery has been charged to a sufficient level. Battery Saver won’t reactivate until the battery is low again."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Phone <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Device <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Battery Saver is off. Features no longer restricted."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Battery Saver turned off. Features no longer restricted."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Battery Saver turned off"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Phone has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Device has enough charge. Features no longer restricted."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android application"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 33a8488..da89793 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Storage"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Files and media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"access photos, media and files on your device"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingerprint gestures"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Empty"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Battery Saver"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Battery Saver won’t reactivate until battery low again"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Battery has been charged to a sufficient level. Battery Saver won’t reactivate until the battery is low again."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Phone <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Device <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> charged"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Battery Saver is off. Features no longer restricted."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Battery Saver turned off. Features no longer restricted."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Battery Saver turned off"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Phone has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet has enough charge. Features no longer restricted."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Device has enough charge. Features no longer restricted."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android application"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index e256605..f7da05e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎access your calendar‎‏‎‎‏‎"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎SMS‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎send and view SMS messages‎‏‎‎‏‎"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎Storage‎‏‎‎‏‎"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎Files and media‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎access photos, media, and files on your device‎‏‎‎‏‎"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎Microphone‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‎record audio‎‏‎‎‏‎"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎Can tap, swipe, pinch, and perform other gestures.‎‏‎‎‏‎"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎Fingerprint gestures‎‏‎‎‏‎"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎Can capture gestures performed on the device\'s fingerprint sensor.‎‏‎‎‏‎"</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎Take screenshot‎‏‎‎‏‎"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎Can take a screenshot of the display.‎‏‎‎‏‎"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎disable or modify status bar‎‏‎‎‏‎"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎Allows the app to disable the status bar or add and remove system icons.‎‏‎‎‏‎"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎be the status bar‎‏‎‎‏‎"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎Raise volume above recommended level?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Listening at high volume for long periods may damage your hearing.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎Use Accessibility Shortcut?‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ Current accessibility feature:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ You can change the feature in Settings &gt; Accessibility.‎‏‎‎‏‎"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎Empty‎‏‎‎‏‎"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎Edit shortcuts‎‏‎‎‏‎"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎Turn off Shortcut‎‏‎‎‏‎"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎Use Shortcut‎‏‎‎‏‎"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Color Inversion‎‏‎‎‏‎"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‎‎‎Turn on work profile?‎‏‎‎‏‎"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎Your work apps, notifications, data, and other work profile features will be turned on‎‏‎‎‏‎"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎Turn on‎‏‎‎‏‎"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎App is not available‎‏‎‎‏‎"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is not available right now.‎‏‎‎‏‎"</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer.‎‏‎‎‏‎"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎Check for update‎‏‎‎‏‎"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎You have new messages‎‏‎‎‏‎"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎Battery may run out before usual charge‎‏‎‎‏‎"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎Battery Saver activated to extend battery life‎‏‎‎‏‎"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎Battery Saver‎‏‎‎‏‎"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎Battery Saver won’t reactivate until battery low again‎‏‎‎‏‎"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎Battery has been charged to a sufficient level. Battery Saver won’t reactivate until the battery is low again.‎‏‎‎‏‎"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‎Phone ‎‏‎‎‏‏‎<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ charged‎‏‎‎‏‎"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎Tablet ‎‏‎‎‏‏‎<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ charged‎‏‎‎‏‎"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎Device ‎‏‎‎‏‏‎<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ charged‎‏‎‎‏‎"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎Battery Saver is off. Features no longer restricted.‎‏‎‎‏‎"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎Battery Saver turned off. Features no longer restricted.‎‏‎‎‏‎"</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎Battery Saver turned off‎‏‎‎‏‎"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎Phone has enough charge. Features no longer restricted.‎‏‎‎‏‎"</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎Tablet has enough charge. Features no longer restricted.‎‏‎‎‏‎"</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎Device has enough charge. Features no longer restricted.‎‏‎‎‏‎"</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎Folder‎‏‎‎‏‎"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎Android application‎‏‎‎‏‎"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎File‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index ad861f2..aeec9f8 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder al calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Almacenamiento"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Archivos y contenido multimedia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"acceder a las fotos, el contenido multimedia y los archivos"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabar audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Permite presionar, deslizar, pellizcar y usar otros gestos."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos del sensor de huellas digitales"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Captura los gestos que se hacen en el sensor de huellas digitales del dispositivo."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tomar captura de pantalla"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede tomar una captura de la pantalla."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar a un alto volumen durante largos períodos puede dañar tu audición."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Usar acceso directo de accesibilidad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Cuando el acceso directo está activado, puedes presionar los botones de volumen durante 3 segundos para iniciar una función de accesibilidad.\n\n Función de accesibilidad actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puedes cambiar la función en Configuración &gt; Accesibilidad."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Vacío"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"¿Activar el perfil de trabajo?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Se activaran las apps de trabajo, los datos, las notificaciones y otras funciones del perfil de trabajo"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta app se creó para una versión anterior de Android y es posible que no funcione correctamente. Busca actualizaciones o comunícate con el programador."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Es posible que la batería se agote antes de la carga habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se activó el Ahorro de batería para extender la duración de la batería"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ahorro de batería"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"El Ahorro de batería no se volverá a activar hasta que la batería esté baja otra vez"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"La batería tiene suficiente carga. El Ahorro de batería no se volverá a activar hasta que la batería esté baja otra vez."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Nivel de batería: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Nivel de batería de la tablet: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Nivel de batería del dispositivo: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"El Ahorro de batería está desactivado. Ya no se restringen las funciones."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Se desactivó el Ahorro de batería. Ya no se restringen las funciones."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Se desactivó el Ahorro de batería"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"El teléfono tiene suficiente carga. Ya no se restringen las funciones."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"La tablet tiene suficiente carga. Ya no se restringen las funciones."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"El dispositivo tiene suficiente carga. Ya no se restringen las funciones."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Carpeta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación de Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Archivo"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 9c64369..1ef891a 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder a tu calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Almacenamiento"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Archivos y contenido multimedia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"acceder a fotos, contenido multimedia y archivos de tu dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabar audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Puedes tocar y pellizcar la pantalla, deslizar el dedo y hacer otros gestos."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos de huellas digitales"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Puede capturar los gestos realizados en el sensor de huellas digitales del dispositivo."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Hacer captura de pantalla"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede hacer capturas de la pantalla."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"inhabilitar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o añada y elimine iconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos fuertes durante mucho tiempo puede dañar los oídos."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Utilizar acceso directo de accesibilidad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Si el acceso directo está activado, pulsa los dos botones de volumen durante tres segundos para iniciar una función de accesibilidad.\n\n Función de accesibilidad actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puedes cambiar la función en Ajustes &gt; Accesibilidad."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Vacío"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"¿Activar el perfil de trabajo?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Tus aplicaciones, notificaciones, datos y otras funciones del perfil de trabajo se activarán"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta aplicación se ha diseñado para una versión anterior de Android y es posible que no funcione correctamente. Busca actualizaciones o ponte en contacto con el desarrollador."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualizaciones"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Es posible que te quedes sin batería antes de lo habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se ha activado el ahorro de batería para aumentar la duración de la batería"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ahorro de batería"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"El modo Ahorro de batería no se activará hasta que la batería vuelva a estar baja"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"La batería se ha cargado lo suficiente. El modo Ahorro de batería no se activará hasta que la batería vuelva a estar baja."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Nivel de la batería del teléfono: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Nivel de batería del tablet: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Nivel de la batería del dispositivo: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Ahorro de batería desactivado. Las funciones ya no están restringidas."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Ahorro de batería desactivado. Las funciones ya no están restringidas."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ahorro de batería desactivado"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"El teléfono tiene suficiente batería. Las funciones ya no están restringidas."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"El tablet tiene suficiente batería. Las funciones ya no están restringidas."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"El dispositivo tiene suficiente batería. Las funciones ya no están restringidas."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Carpeta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación de Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Archivo"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index c9e74b3..9a4b6d3 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"juurdepääs kalendrile"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"saata ja vaadata SMS-sõnumeid"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Mäluruum"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"juurdepääs seadmesse salvestatud fotodele, meediasisule ja failidele"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"heli salvestamine"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Saate puudutada, pühkida, sõrmi kokku-lahku liigutada ja teisi liigutusi teha."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Sõrmejälje liigutused"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Teil on võimalik jäädvustada seadme sõrmejäljeanduril tehtud liigutused."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"keela või muuda olekuriba"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"olekuribana kuvamine"</string>
@@ -1454,7 +1459,7 @@
     <string name="sync_really_delete" msgid="5657871730315579051">"Kustuta üksused"</string>
     <string name="sync_undo_deletes" msgid="5786033331266418896">"Võtke kustutamised tagasi"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"Ära tee praegu midagi"</string>
-    <string name="choose_account_label" msgid="5557833752759831548">"Konto valimine"</string>
+    <string name="choose_account_label" msgid="5557833752759831548">"Valige konto"</string>
     <string name="add_account_label" msgid="4067610644298737417">"Konto lisamine"</string>
     <string name="add_account_button_label" msgid="322390749416414097">"Lisa konto"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Suurendamine"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Kas suurendada helitugevuse taset üle soovitatud taseme?\n\nPikaajaline valju helitugevusega kuulamine võib kuulmist kahjustada."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Kas kasutada juurdepääsetavuse otseteed?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kui otsetee on sisse lülitatud, käivitab mõlema helitugevuse nupu kolm sekundit all hoidmine juurdepääsetavuse funktsiooni.\n\n Praegune juurdepääsetavuse funktsioon:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Saate seda funktsiooni muuta valikutega Seaded &gt; Juurdepääsetavus."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Tühi"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Muuda otseteid"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Tühista"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Lülita otsetee välja"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Kas lülitada tööprofiil sisse?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Teie töörakendused, märguanded, andmed ja muud tööprofiili funktsioonid lülitatakse sisse"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Lülita sisse"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"See rakendus on loodud Androidi vanema versiooni jaoks ega pruugi õigesti töötada. Otsige värskendusi või võtke ühendust arendajaga."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Otsi värskendust"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Teile on uusi sõnumeid"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Aku võib enne tavapärast laadimist tühjaks saada"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akusäästja aktiveeriti aku tööea pikendamiseks"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akusäästja"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Akusäästja lülitatakse uuesti sisse, kui aku hakkab tühjaks saama"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Aku on piisavalt laetud. Akusäästja lülitatakse uuesti sisse, kui aku hakkab tühjaks saama."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon on <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> laetud"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tahvelarvuti on <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> laetud"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Seade on <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> laetud"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Akusäästja on välja lülitatud. Funktsioonid ei ole enam piiratud."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Akusäästja on välja lülitatud. Funktsioonid ei ole enam piiratud."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Kaust"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Androidi rakendus"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fail"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index cae6b99..f0a0010c 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"atzitu egutegia"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS mezuak"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"bidali eta ikusi SMS mezuak"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Memoria"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"atzitu gailuko argazkiak, multimedia-edukia eta fitxategiak"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonoa"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabatu audioa"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Sakatu, lerratu, atximurkatu eta beste hainbat keinu egin ditzake."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Hatz-marken keinuak"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Gailuaren hatz-marken sentsorean egindako keinuak atzeman ditzake."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"desgaitu edo aldatu egoera-barra"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"bihurtu egoera-barra"</string>
@@ -1306,7 +1311,7 @@
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Erantsitako gailua ez da telefono honekin bateragarria. Sakatu informazio gehiago lortzeko."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"USB bidezko arazketa konektatuta"</string>
     <string name="adb_active_notification_message" msgid="5617264033476778211">"Sakatu USB bidezko arazketa desaktibatzeko"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Hautatu USB arazketa desgaitzeko."</string>
+    <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Hautatu USB bidezko arazketa desgaitzeko."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Proba-materialeko modua gaitu da"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serie-kontsola gaituta dago"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bolumena gomendatutako mailatik gora igo nahi duzu?\n\nMusika bolumen handian eta denbora luzez entzuteak entzumena kalte diezazuke."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erabilerraztasun-lasterbidea erabili nahi duzu?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Lasterbidea aktibatuta dagoenean, bi bolumen-botoiak hiru segundoz sakatuta abiaraziko da erabilerraztasun-eginbidea.\n\n Uneko erabilerraztasun-eginbidea:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Eginbidea aldatzeko, joan Ezarpenak &gt; Erabilerraztasuna atalera."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Hustu"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editatu lasterbideak"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Utzi"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desaktibatu lasterbidea"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Laneko profila aktibatu?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Laneko aplikazioak, jakinarazpenak, datuak eta laneko profileko bestelako eginbideak aktibatuko dira"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aktibatu"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Aplikazioa Android-en bertsio zaharrago baterako sortu zenez, baliteke behar bezala ez funtzionatzea. Bilatu eguneratzerik baden, edo jarri garatzailearekin harremanetan."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Bilatu eguneratzeak"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Mezu berriak dituzu"</string>
@@ -1874,7 +1886,7 @@
     <string name="app_category_maps" msgid="6395725487922533156">"Mapak eta nabigazioa"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"Produktibitatea"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Gailuaren memoria"</string>
-    <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB arazketa"</string>
+    <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB bidezko arazketa"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"ordu"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"minutu"</string>
     <string name="time_picker_header_text" msgid="9073802285051516688">"Ezarri ordua"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baliteke bateria ohi baino lehenago agortzea"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Bateria-aurrezlea aktibatuta dago bateriaren iraupena luzatzeko"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Bateria-aurrezlea"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Bateria-aurrezlea ez da aktibatuko berriro bateria gutxi gelditzen den arte"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Kargatu da behar adina bateria. Bateria-aurrezlea ez da aktibatuko berriro bateria gutxi gelditzen den arte."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefonoaren bateria: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tabletaren bateria: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Gailuaren bateria: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Desaktibatu egin da bateria-aurrezlea. Jada ez dago eginbiderik murriztuta."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Desaktibatu egin da bateria-aurrezlea. Jada ez dago eginbiderik murriztuta."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Karpeta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-erako aplikazioa"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fitxategia"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b45c6f9..7d12221 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"دسترسی به تقویم شما"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"پیامک"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ارسال و مشاهده پیامک‌ها"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"حافظه"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"دسترسی به عکس‌ها، رسانه‌ها و فایل‌های روی دستگاهتان"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"میکروفن"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ضبط صدا"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"می‌توانید ضربه بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشاره‌های دیگری اجرا کنید."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"اشاره‌های اثر انگشت"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"می‌تواند اشاره‌های اجرا‌شده روی حسگر اثرانگشت دستگاه را ثبت کند."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"غیرفعال کردن یا تغییر نوار وضعیت"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"‏به برنامه اجازه می‎دهد تا نوار وضعیت را غیرفعال کند یا نمادهای سیستم را اضافه یا حذف کند."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"نوار وضعیت باشد"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"میزان صدا را به بالاتر از حد توصیه شده افزایش می‌دهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی می‌تواند به شنوایی‌تان آسیب وارد کند."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"از میان‌بر دسترس‌پذیری استفاده شود؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"وقتی میان‌بر روشن است،‌ اگر هر دو دکمه صدا را ۳ ثانیه فشار دهید یکی از قابلیت‌های دسترس‌پذیری شروع می‌شود.\n\n قابلیت دسترس‌پذیری کنونی:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n می‌توانید در «تنظیمات &gt; دسترس‌پذیری»، قابلیت را تغییر دهید."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"خالی"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ویرایش میان‌برها"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"لغو"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"خاموش کردن میان‌بر"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استفاده از میان‌بر"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"وارونگی رنگ"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"نمایه کاری روشن شود؟"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"برنامه‌ها، اعلان‌ها، داده‌ها و سایر قابلیت‌های نمایه کاری شما روشن خواهد شد"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"روشن کردن"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏این برنامه برای نسخه قدیمی‌تری از Android ساخته شده است و ممکن است درست کار نکند. وجود به‌روزرسانی را بررسی کنید یا با برنامه‌نویس تماس بگیرید."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"بررسی وجود به‌روزرسانی"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"پیام‌های جدیدی دارید"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ممکن است شارژ باتری قبل از شارژ معمول تمام شود"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"جهت افزایش عمر باتری، «بهینه‌سازی باتری» فعال شد"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"بهینه‌سازی باتری"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"تا وقتی شارژ باتری دوباره به سطح پایین نرسد، «بهینه‌سازی باتری» مجدداً فعال نخواهد شد"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"باتری درحد کافی شارژ شده است. تا وقتی شارژ باتری دوباره به سطح پایین نرسد، «بهینه‌سازی باتری» مجدداً فعال نخواهد شد."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"تلفن <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> شارژ شد"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"رایانه لوحی <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> شارژ شد"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"دستگاه <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> شارژ شد"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"«بهینه‌سازی باتری» خاموش است. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"«بهینه‌سازی باتری» خاموش شد. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"پوشه"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"‏برنامه Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"فایل"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c1df18e..ba39b8c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"käyttää kalenteria"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Tallennustila"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"käyttää laitteellesi tallennettuja valokuvia, mediatiedostoja ja muita tiedostoja"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa ääntä"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Lupa napauttaa, pyyhkäistä, nipistää ja käyttää muita eleitä."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Sormenjälkieleet"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Voi tallentaa laitteen sormenjälkitunnistimelle tehtyjä eleitä."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"sijaita tilapalkissa"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Nostetaanko äänenvoimakkuus suositellun tason yläpuolelle?\n\nPitkäkestoinen kova äänenvoimakkuus saattaa heikentää kuuloa."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Käytetäänkö esteettömyyden pikanäppäintä?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kun pikanäppäin on käytössä, voit käynnistää esteettömyystoiminnon pitämällä molempia äänenvoimakkuuspainikkeita painettuna kolmen sekunnin ajan.\n\n Tällä hetkellä valittu esteettömyystoiminto:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Voit vaihtaa toimintoa valitsemalla Asetukset &gt; Esteettömyys."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Tyhjennä"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Muokkaa pikakuvakkeita"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Peruuta"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Poista pikanäppäin käytöstä"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Käytä pikanäppäintä"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Käänteiset värit"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Otetaanko työprofiili käyttöön?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Työsovellukset, ‑ilmoitukset, ‑tiedot ja muut työprofiiliominaisuudet otetaan käyttöön"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ota käyttöön"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Tämä sovellus on suunniteltu vanhemmalle Android-versiolle eikä välttämättä toimi oikein. Kokeile tarkistaa päivitykset tai ottaa yhteyttä kehittäjään."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tarkista päivitykset"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Sinulle on uusia viestejä"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akku saattaa loppua ennen normaalia latausaikaa"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Virransäästö otettu käyttöön akunkeston pidentämiseksi"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Virransäästö"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Virransäästö aktivoituu uudelleen vasta, kun akku on lähes tyhjä"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Akun varaus on riittävä. Virransäästö aktivoituu uudelleen vasta, kun akku on lähes tyhjä."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Puhelin <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ladattu"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tabletti <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ladattu"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Laite <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ladattu"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Virransäästö ei ole käytössä. Ominaisuuksia ei enää rajoiteta."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Virransäästö poistettiin käytöstä. Ominaisuuksia ei enää rajoiteta."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Kansio"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-sovellus"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Tiedosto"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 9f2647d..8df6ad6 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Messagerie texte"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et afficher des messages texte"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Stockage"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"accéder aux photos, aux contenus multimédias et aux fichiers sur votre appareil"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Peut toucher, balayer, pincer et effectuer d\'autres gestes."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestes sur le capteur d\'empreintes digitales"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut capturer des gestes effectués sur le capteur d\'empreintes digitales de l\'appareil."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"désactiver ou modifier la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"servir de barre d\'état"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au-dessus du niveau recommandé?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour lancer une fonctionnalité d\'accessibilité.\n\n Fonctionnalité d\'accessibilité utilisée actuellement :\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Vous pouvez changer de fonctionnalité sous Paramètres &gt; Accessibilité."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Vide"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifier les raccourcis"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuler"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Désactiver le raccourci"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Activer le profil professionnel?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Vos applications professionnelles, vos notifications, vos données et les autres fonctionnalités de profil professionnel seront activées"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activer"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Cette application a été conçue pour une ancienne version d\'Android et pourrait ne pas fonctionner correctement. Essayez de vérifier les mises à jour ou communiquez avec son concepteur."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"La pile pourrait s\'épuiser avant la charge habituelle"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Le mode Économiseur de pile est activé afin de prolonger l\'autonomie"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Économiseur de pile"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Le mode Économiseur de pile ne se réactivera seulement lorsque la pile deviendra faible à nouveau"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"La pile a été suffisamment chargée. Le mode Économiseur de pile ne se réactivera seulement lorsque la pile deviendra faible à nouveau."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Téléphone chargé à <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablette chargée à <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Appareil chargé à <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Le mode Économiseur de pile est désactivé. Ces fonctionnalités ne sont plus restreintes."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Le mode Économiseur de pile est désactivé. Ces fonctionnalités ne sont plus restreintes."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Dossier"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Application Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fichier"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7d80653..a64066a 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et consulter des SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Stockage"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Fichiers et contenus multimédias"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"accéder aux photos, contenus multimédias et fichiers sur votre appareil"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Permet d\'appuyer sur l\'écran, de le balayer, de le pincer et d\'effectuer d\'autres gestes."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestes avec l\'empreinte digitale"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut enregistrer des gestes effectués sur le lecteur d\'empreinte digitale de l\'appareil."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Prendre une capture d\'écran"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Peut prendre des captures d\'écran."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"Désactivation ou modification de la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"remplacer la barre d\'état"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au dessus du niveau recommandé ?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour lancer une fonctionnalité d\'accessibilité.\n\n Fonctionnalité d\'accessibilité utilisée actuellement :\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Vous pouvez changer de fonctionnalité dans Paramètres &gt; Accessibilité."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Vider"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifier les raccourcis"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuler"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Désactiver le raccourci"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Activer profil professionnel ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Vos applications professionnelles, notifications, données et d\'autres fonctionnalités de votre profil professionnel seront activées"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activer"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Cette application a été conçue pour une ancienne version d\'Android et risque de ne pas fonctionner correctement. Recherchez des mises à jour ou contactez le développeur."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rechercher une mise à jour"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Vous risquez d\'être à court de batterie plus tôt que prévu"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Économiseur de batterie activé pour prolonger l\'autonomie"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Économiseur de batterie"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"L\'économiseur d\'écran ne se réactivera que lorsque le niveau de la batterie sera à nouveau faible"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Le niveau de charge de la batterie est suffisant. L\'économiseur de batterie ne se réactivera que lorsque le niveau de la batterie sera à nouveau faible."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Téléphone chargé à <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablette chargée à <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Appareil chargé à <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Économiseur de batterie désactivé. Les fonctionnalités ne sont plus restreintes."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Économiseur de batterie désactivé. Les fonctionnalités ne sont plus restreintes."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Économiseur de batterie désactivé"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Téléphone suffisamment chargé. Les fonctionnalités ne sont plus restreintes."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablette suffisamment chargée. Les fonctionnalités ne sont plus restreintes."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Appareil suffisamment chargé. Les fonctionnalités ne sont plus restreintes."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Dossier"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Application Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fichier"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index eebe5ab..df08abc 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder ao teu calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e consultar mensaxes de SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Almacenamento"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Ficheiros e contido multimedia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"acceder a fotos, contido multimedia e ficheiros no teu dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Podes tocar, pasar o dedo, beliscar e realizar outros xestos."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Xestos de impresión dixital"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode rexistrar os xestos realizados no sensor de impresión dixital do dispositivo."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Facer captura de pantalla"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode facer capturas de pantalla."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar ou modificar a barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite á aplicación desactivar a barra de estado ou engadir e eliminar as iconas do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"actuar como a barra de estado"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Queres subir o volume máis do nivel recomendado?\n\nA reprodución de son a un volume elevado durante moito tempo pode provocar danos nos oídos."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Queres utilizar o atallo de accesibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Cando o atallo está activado, podes premer os dous botóns de volume durante 3 segundos para iniciar unha función de accesibilidade.\n\n Función de accesibilidade actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Podes cambiar a función en Configuración &gt; Accesibilidade."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Baleirar"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atallos"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar atallo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Activar o perfil de traballo?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Activaranse as túas aplicacións de traballo, as notificacións, os datos e outras funcións do perfil de traballo"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"A aplicación non está dispoñible"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> non está dispoñible neste momento."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta aplicación deseñouse para unha versión anterior de Android e quizais non funcione correctamente. Proba a buscar actualizacións ou contacta co programador."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Tes mensaxes novas"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A batería pode esgotarse antes do habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Para ampliar a duración da batería activouse a función Aforro de batería"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Aforro de batería"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"A función Aforro de batería non se activará de novo ata que volva quedar pouca batería"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"A batería cargouse ata un nivel suficiente. A función Aforro de batería non se activará de novo ata que volva quedar pouca batería."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Nivel de batería do teléfono: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Nivel de batería da tableta: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Nivel de batería do dispositivo: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"A función Aforro de batería está desactivada. Xa non se restrinxirá ningunha función."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Desactivouse a función Aforro de batería. Xa non se restrinxirá ningunha función."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Desactivouse a función Aforro de batería."</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"O teléfono non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"A tableta non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"O dispositivo non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Cartafol"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicación Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Ficheiro"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 869a752..f663b87 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -247,7 +247,7 @@
     <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"એરપ્લેન મોડ"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"એરપ્લેન મોડ ચાલુ છે."</string>
     <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"એરપ્લેન મોડ બંધ છે."</string>
-    <string name="global_action_settings" msgid="4671878836947494217">"સેટિંગ્સ"</string>
+    <string name="global_action_settings" msgid="4671878836947494217">"સેટિંગ"</string>
     <string name="global_action_assist" msgid="2517047220311505805">"સહાય"</string>
     <string name="global_action_voice_assist" msgid="6655788068555086695">"વૉઇસ સહાય"</string>
     <string name="global_action_lockdown" msgid="2475471405907902963">"લૉકડાઉન"</string>
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS સંદેશા મોકલવાની અને જોવાની"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"સ્ટોરેજ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"તમારા ઉપકરણ પર ફોટો, મીડિયા અને ફાઇલો ઍક્સેસ કરવાની"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"માઇક્રોફોન"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ઑડિઓ રેકોર્ડ કરવાની"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ટૅપ, સ્વાઇપ, પિંચ કરી અને અન્ય હાવભાવ કરી શકે છે."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ફિંગરપ્રિન્ટ સંકેતો"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ડિવાઇસના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"સ્ટેટસ બારને અક્ષમ કરો અથવા તેમાં ફેરફાર કરો"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ઍપ્લિકેશનને સ્ટેટસ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"સ્ટેટસ બારમાં બતાવો"</string>
@@ -1552,7 +1557,7 @@
     <string name="media_route_chooser_title" msgid="6646594924991269208">"ઉપકરણ સાથે કનેક્ટ કરો"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ઉપકરણ પર સ્ક્રીન કાસ્ટ કરો"</string>
     <string name="media_route_chooser_searching" msgid="6119673534251329535">"ઉપકરણો માટે શોધી રહ્યું છે…"</string>
-    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"સેટિંગ્સ"</string>
+    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"સેટિંગ"</string>
     <string name="media_route_controller_disconnect" msgid="7362617572732576959">"ડિસ્કનેક્ટ કરો"</string>
     <string name="media_route_status_scanning" msgid="8045156315309594482">"સ્કેન કરી રહ્યું છે..."</string>
     <string name="media_route_status_connecting" msgid="5845597961412010540">"કનેક્ટ કરી રહ્યું છે..."</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ભલામણ કરેલ સ્તરની ઉપર વૉલ્યૂમ વધાર્યો?\n\nલાંબા સમય સુધી ઊંચા અવાજે સાંભળવું તમારી શ્રવણક્ષમતાને નુકસાન પહોંચાડી શકે છે."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ઍક્સેસિબિલિટી શૉર્ટકટનો ઉપયોગ કરીએ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"જ્યારે શૉર્ટકટ ચાલુ હોય, ત્યારે બન્ને વૉલ્યૂમ બટનને 3 સેકન્ડ સુધી દબાવી રાખવાથી ઍક્સેસિબિલિટી સુવિધા શરૂ થઈ જશે.\n\n વર્તમાન ઍક્સેસિબિલિટી સુવિધા:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n તમે સેટિંગ્સ &gt; ઍક્સેસિબિલિટીમાં જઈને આ સુવિધા બદલી શકો છો."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ખાલી કરો"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"શૉર્ટકટમાં ફેરફાર કરો"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"રદ કરો"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"શૉર્ટકટ બંધ કરો"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"શૉર્ટકટનો ઉપયોગ કરો"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"રંગનો વ્યુત્ક્રમ"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"કાર્યાલયની પ્રોફાઇલ ચાલુ કરીએ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"તમારી કાર્યાલયની ઍપ, નોટિફિકેશન, ડેટા અને અન્ય કાર્યાલયની પ્રોફાઇલ સુવિધાઓ ચાલુ કરવામાં આવશે"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ચાલુ કરો"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"આ ઍપ Androidના જૂના વર્ઝન માટે બનાવવામાં આવ્યું હતું અને તે કદાચ તે યોગ્ય રીતે કાર્ય કરી શકશે નહીં. અપડેટ માટે તપાસવાનો પ્રયાસ કરો અથવા ડેવલપરનો સંપર્ક કરો."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"અપડેટ માટે તપાસો"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"તમારી પાસે નવા સંદેશા છે"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"સામાન્ય રીતે ચાર્જ કરવાના સમય પહેલાં બૅટરી સમાપ્ત થઈ શકે છે"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"બૅટરી આવરદા વધારવા માટે બૅટરી સેવર ચાલુ કર્યું"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"બૅટરી સેવર"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"બૅટરી ફરીથી ઓછી નહીં થાય ત્યાં સુધી બૅટરી સેવર ફરીથી સક્રિય નહીં થાય"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"બૅટરી પૂરતા લેવલ સુધી ચાર્જ થઈ ગઈ છે. બૅટરી ફરીથી ઓછી નહીં થાય ત્યાં સુધી બૅટરી સેવર ફરીથી સક્રિય નહીં થાય"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ફોન <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ચાર્જ થયો છે"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ટૅબ્લેટ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ચાર્જ થયું છે"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ડિવાઇસ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ચાર્જ થયું છે"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"બૅટરી સેવર બંધ છે. સુવિધાઓ હવે મર્યાદિત નથી."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"બૅટરી સેવર બંધ કર્યું. સુવિધાઓ હવે મર્યાદિત નથી."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ફોલ્ડર"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ઍપ"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ફાઇલ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 612854c..8105441 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करने"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"मेमोरी"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"अपने डिवाइस पर मौजूद फ़ोटो, मीडिया और फ़ाइलें ऐक्सेस करने की"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफ़ोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडियो रिकॉर्ड करें"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"इस सेवा के ज़रिए टैप, स्वाइप, पिंच और बाकी जेस्चर किए जा सकते हैं."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"फ़िंगरप्रिंट जेस्चर"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिवाइस के फ़िंगरप्रिंट सेंसर पर किए गए हाथ के जेस्चर (स्पर्श) कैप्चर किए जा सकते हैं."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार को अक्षम करें या बदलें"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ऐप को, स्टेटस बार को बंद करने या सिस्‍टम आइकॉन को जोड़ने और निकालने की अनुमति देता है."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार को रहने दें"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"वॉल्यूम को सुझाए गए स्तर से ऊपर बढ़ाएं?\n\nअत्यधिक वॉल्यूम पर ज़्यादा समय तक सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"सुलभता शॉर्टकट का इस्तेमाल करना चाहते हैं?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"इस शॉर्टकट के चालू होने पर, दोनों वॉल्यूम बटनों को 3 सेकंड तक दबाने से सुलभता सुविधा शुरू हो जाएगी.\n\n मौजूदा सुलभता सुविधा:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n आप इस सुविधा को सेटिंग &gt; सुलभता पर जाकर बदल सकते हैं."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"खाली करें"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"शॉर्टकट में बदलाव करें"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"अभी नहीं"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"शॉर्टकट बंद करें"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट का उपयोग करें"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रंग बदलने की सुविधा"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"वर्क प्रोफ़ाइल चालू करें?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"आपके काम से जुड़े ऐप्लिकेशन, सूचनाएं, डेटा और वर्क प्रोफ़ाइल से जुड़ी दूसरी सुविधाएं चालू हो जाएंगी"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"चालू करें"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"यह ऐप्लिकेशन Android के पुराने वर्शन के लिए बनाया गया था, इसलिए हो सकता है कि यह सही से काम न करे. देखें कि अपडेट मौजूद हैं या नहीं, या फिर डेवलपर से संपर्क करें."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"देखें कि अपडेट मौजूद है या नहीं"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"आपके पास नए संदेश हैं"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"बैटरी आम तौर पर जितने समय चलती है, उससे पहले खत्म हो सकती है"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"बैटरी लाइफ़ बढ़ाने के लिए \'बैटरी सेवर\' चालू हो गया है"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"बैटरी सेवर"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"जब तक कि बैटरी फिर से कम नहीं हो जाती, तब तक बैटरी सेवर फिर से चालू नहीं होगा"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"बैटरी ज़रूरत भर की चार्ज हो गई है. जब तक कि बैटरी फिर से कम नहीं हो जाती, तब तक बैटरी सेवर फिर से चालू नहीं होगा."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"फ़ोन <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज हो गया"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"टैबलेट <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> प्रतिशत चार्ज हो गया है"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"डिवाइस <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज हो गया"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"बैटरी सेवर बंद है. सुविधाओं पर अब पाबंदी नहीं है."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"बैटरी सेवर बंद कर दिया गया है. सुविधाओं पर अब पाबंदी नहीं है."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"फ़ोल्डर"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ऐप्लिकेशन"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"फ़ाइल"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0b7a357..9737187 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -290,7 +290,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupati kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"slati i pregledavati SMS poruke"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Prostor za pohranu"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Datoteke i mediji"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"pristupiti fotografijama, medijima i datotekama na vašem uređaju"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snimati zvuk"</string>
@@ -316,6 +316,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Može dodirnuti, prijeći prstom, spojiti prste i izvoditi druge pokrete."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Pokreti za otisak prsta"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može snimati pokrete izvršene na senzoru otiska prsta na uređaju."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Snimi zaslon"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Možete napraviti snimku zaslona."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmjena trake statusa"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Aplikaciji omogućuje onemogućavanje trake statusa ili dodavanje i uklanjanje sistemskih ikona."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"biti traka statusa"</string>
@@ -1632,6 +1634,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučene razine?\n\nDugotrajno slušanje glasne glazbe može vam oštetiti sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li upotrebljavati prečac za pristupačnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kada je taj prečac uključen, pritiskom na obje tipke za glasnoću na 3 sekunde pokrenut će se značajka pristupačnosti.\n\n Trenutačna značajka pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Značajku možete promijeniti u Postavkama &gt; Pristupačnost."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Prazno"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi prečace"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Otkaži"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečac"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
@@ -1877,6 +1882,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Želite uključiti radni profil?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Uključit će se vaše radne aplikacije, obavijesti, podaci i druge značajke radnog profila"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutačno nije dostupna."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova je aplikacija razvijena za stariju verziju Androida i možda neće funkcionirati pravilno. Potražite ažuriranja ili se obratite razvojnom programeru."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri ažuriranja"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
@@ -1988,13 +1995,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija se može isprazniti prije uobičajenog vremena punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Štednja baterije aktivirana je kako bi se produljilo trajanje baterije"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Štednja baterije"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Štednja baterije neće se ponovo aktivirati dok baterija opet ne postane slaba"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Baterija je napunjena do zadovoljavajuće razine. Štednja baterije neće se ponovo aktivirati dok baterija opet ne postane slaba."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Uređaj je napunjen <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Isključena je Štednja baterije. Značajke više nisu ograničene."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Isključena je Štednja baterije. Značajke više nisu ograničene."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Isključena je Štednja baterije"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterija mobilnog telefona dovoljno je napunjena. Značajke više nisu ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Baterija tableta dovoljno je napunjena. Značajke više nisu ograničene."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Baterija uređaja dovoljno je napunjena. Značajke više nisu ograničene."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Mapa"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android aplikacija"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Datoteka"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index cc53c7b..4884cf7 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"hozzáférés a naptárhoz"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS-ek küldése és megtekintése"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Tárhely"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Fájlok és média"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"az eszközön lévő fotók, médiatartalmak és fájlok elérése"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"hanganyag rögzítése"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Koppintás, ujjak gyors csúsztatása és összehúzása, illetve egyéb kézmozdulatok végrehajtása."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Kézmozdulatok az ujjlenyomat-érzékelőn"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Érzékeli az eszköz ujjlenyomat-érzékelőjén végzett kézmozdulatokat."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Képernyőkép készítése"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Készíthet képernyőképet a kijelzőről."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"állapotsor kikapcsolása vagy módosítása"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Lehetővé teszi az alkalmazás számára az állapotsor kikapcsolását, illetve rendszerikonok hozzáadását és eltávolítását."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"az állapotsor szerepének átvétele"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Az ajánlott szint fölé szeretné emelni a hangerőt?\n\nHa hosszú időn át teszi ki magát nagy hangerőnek, azzal károsíthatja a hallását."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Szeretné használni a Kisegítő lehetőségek billentyűparancsot?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Ha be van kapcsolva a billentyűparancs, a két hangerőgomb 3 másodpercig tartó lenyomásával elindíthatja a kisegítő lehetőségek egyik funkcióját.\n\n A kisegítő lehetőségek jelenleg beállított funkciója:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n A funkciót a Beállítások &gt; Kisegítő lehetőségek menüpontban módosíthatja."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Üres"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Gyorsparancsszerkesztés"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Mégse"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Billentyűparancs kikapcsolása"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Billentyűparancs használata"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Színek invertálása"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Bekapcsolja a munkaprofilt?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"A munkahelyi alkalmazások, értesítések, adatok és a munkaprofilhoz tartozó egyéb funkciók be lesznek kapcsolva"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Bekapcsolás"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ez az alkalmazás az Android egyik korábbi verziójához készült, így elképzelhető, hogy nem működik majd megfelelően ezen a rendszeren. Keressen frissítéseket, vagy vegye fel a kapcsolatot a fejlesztővel."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Frissítés keresése"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Új üzenetei érkeztek"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Előfordulhat, hogy az akkumulátor lemerül a szokásos töltési időszak előtt"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akkumulátorkímélő mód aktiválva az akkumulátor üzemidejének növelése érdekében"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akkumulátorkímélő mód"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Az Akkumulátorkímélő mód nem aktiválódik újra addig, amíg az akkumulátor közel nem kerül a lemerüléshez"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Az akkumulátor töltöttségi szintje elégséges. Az Akkumulátorkímélő mód nem aktiválódik újra addig, amíg az akkumulátor közel nem kerül a lemerüléshez."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"A telefon töltöttségi szintje: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"A táblagép töltöttségi szintje: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Az eszköz töltöttségi szintje: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Akkumulátorkímélő mód kikapcsolva. A funkciók használata most már nincs korlátozva."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Akkumulátorkímélő mód kikapcsolva. A funkciók használata most már nincs korlátozva."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akkumulátorkímélő mód kikapcsolva"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"A telefon töltöttsége elegendő. A funkciók használata már nincs korlátozva."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"A táblagép töltöttsége elegendő. A funkciók használata már nincs korlátozva."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Az eszköz töltöttsége elegendő. A funkciók használata már nincs korlátozva."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Mappa"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-alkalmazás"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fájl"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index e693298..7491539 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"օգտագործել օրացույցը"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ուղարկել և դիտել SMS-ները"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Տարածք"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"օգտագործել լուսանկարները, մեդիա ֆայլերը և ձեր սարքում պահվող մյուս ֆայլերը"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Խոսափող"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ձայնագրել"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Կարող է հպել, թերթել, պտղունցել և կատարել այլ ժեստեր:"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Մատնահետքերի սկաների ժեստեր"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Կարող է արձանագրել մատնահետքերի սկաների վրա կատարվող ժեստերը"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"լինել կարգավիճակի գոտի"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ձայնը բարձրացնե՞լ խորհուրդ տրվող մակարդակից ավել:\n\nԵրկարատև բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Օգտագործե՞լ Մատչելիության դյուրանցումը։"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Հատուկ գործառույթն օգտագործելու համար սեղմեք և 3 վայրկյան սեղմած պահեք ձայնի ուժգնության երկու կոճակները, երբ գործառույթը միացված է։\n\n Մատչելիության ակտիվ գործառույթը՝\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Գործառույթը կարող եք փոփոխել՝ անցնելով Կարգավորումներ &gt; Հատուկ գործառույթներ։"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Դատարկ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Փոփոխել դյուրանցումները"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Չեղարկել"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Անջատել դյուրանցումը"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Օգտագործել դյուրանցումը"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Գունաշրջում"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Միացնե՞լ աշխատանքային պրոֆիլը"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Ձեր աշխատանքային հավելվածները, ծանուցումները, տվյալները և աշխատանքային պրոֆիլի մյուս գործառույթները կմիանան"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Միացնել"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Այս հավելվածը ստեղծվել է Android-ի ավելի հին տարբերակի համար և կարող է պատշաճ չաշխատել: Ստուգեք թարմացումների առկայությունը կամ դիմեք մշակողին:"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Ստուգել նոր տարբերակի առկայությունը"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Դուք ունեք նոր հաղորդագրություններ"</string>
@@ -1858,7 +1870,7 @@
     <string name="pin_specific_target" msgid="7824671240625957415">"Ամրացնել <xliff:g id="LABEL">%1$s</xliff:g> հավելվածը"</string>
     <string name="unpin_target" msgid="3963318576590204447">"Ապամրացնել"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"Ապամրացնել <xliff:g id="LABEL">%1$s</xliff:g> հավելվածը"</string>
-    <string name="app_info" msgid="6113278084877079851">"Հավելվածի տվյալներ"</string>
+    <string name="app_info" msgid="6113278084877079851">"Հավելվածի մասին"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="6577581216125805905">"Ցուցադրական օգտատերը գործարկվում է…"</string>
     <string name="demo_restarting_message" msgid="1160053183701746766">"Սարաքը վերակայվում է…"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Մարտկոցի լիցքը կարող է սովորականից շուտ սպառվել"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Մարտկոցի կյանքը երկարացնելու համար ակտիվացվել է մարտկոցի տնտեսման ռեժիմը"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Մարտկոցի տնտեսում"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Մարտկոցի տնտեսումը նորից կմիանա, երբ մարտկոցի լիցքը ցածր լինի"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Մարտկոցը բավարար լիցքավորված է։ Մարտկոցի տնտեսման ռեժիմը նորից կմիանա, երբ մարտկոցի լիցքը ցածր լինի։"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Հեռախոսի լիցքը՝ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Պլանշետի լիցքը՝ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Սարքի լիցքը՝ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Մարտկոցի տնտեսման ռեժիմն անջատված է: Գործառույթներն այլևս չեն սահմանափակվում։"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Մարտկոցի տնտեսումն անջատված է։ Գործառույթներն այլևս չեն սահմանափակվում։"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Պանակ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android հավելված"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Ֆայլ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 299f23b..9cfe6d9 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"mengirim dan melihat pesan SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Penyimpanan"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"File dan media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"mengakses foto, media, dan file di perangkat"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"merekam audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Dapat mengetuk, menggeser, mencubit, dan melakukan isyarat lainnya."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestur sidik jari"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dapat merekam gestur yang dilakukan di sensor sidik jari perangkat."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ambil screenshot"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Dapat mengambil screenshot tampilan."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"nonaktifkan atau ubah bilah status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Mengizinkan apl menonaktifkan bilah status atau menambah dan menghapus ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"jadikan bilah status"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Mengeraskan volume di atas tingkat yang disarankan?\n\nMendengarkan dengan volume keras dalam waktu yang lama dapat merusak pendengaran Anda."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Aksesibilitas?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Saat pintasan aktif, menekan kedua tombol volume selama 3 detik akan memulai fitur aksesibilitas.\n\n Fitur aksesibilitas saat ini:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Anda dapat mengubah fitur di Setelan &gt; Aksesibilitas."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Kosong"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit pintasan"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Batal"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Nonaktifkan Pintasan"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Aktifkan profil kerja?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikasi kerja, notifikasi, data, dan fitur profil kerja lainnya akan diaktifkan"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aktifkan"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Aplikasi ini dibuat untuk Android versi lama dan mungkin tidak berfungsi sebagaimana mestinya. Coba periksa apakah ada update, atau hubungi developer."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa apakah ada update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Ada pesan baru"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterai mungkin habis sebelum pengisian daya biasanya"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Penghemat Baterai diaktifkan untuk memperpanjang masa pakai baterai"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Penghemat Baterai"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Penghemat Baterai tidak akan aktif lagi sampai baterai lemah kembali"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Baterai telah terisi ke tingkat yang memadai. Penghemat Baterai tidak akan aktif lagi sampai baterai lemah kembali."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Ponsel terisi <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet terisi <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Perangkat terisi <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Penghemat Baterai nonaktif. Fitur tidak lagi dibatasi."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Penghemat Baterai dinonaktifkan. Fitur tidak lagi dibatasi."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Penghemat Baterai dinonaktifkan"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterai ponsel cukup terisi. Fitur tidak lagi dibatasi."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Baterai tablet cukup terisi. Fitur tidak lagi dibatasi."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Baterai perangkat cukup terisi. Fitur tidak lagi dibatasi."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikasi Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index fe55b4c..f7c3b5c 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"fá aðgang að dagatalinu þínu"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"senda og skoða SMS-skilaboð"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Geymslurými"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Skrár og margmiðlunarefni"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"fá aðgang að myndum, efni og skrám í tækinu"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Hljóðnemi"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"taka upp hljóð"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Getur ýtt, strokið, fært fingur saman og gert ýmsar aðrar bendingar."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingrafarabendingar"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Getur fangað bendingar sem eru gerðar á fingrafaralesara tækisins."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Taka skjámynd"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Getur tekið skjámynd af skjánum."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"slökkva á eða breyta stöðustiku"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Leyfir forriti að slökkva á stöðustikunni eða bæta við og fjarlægja kerfistákn."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vera stöðustikan"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Hækka hljóðstyrk umfram ráðlagðan styrk?\n\nEf hlustað er á háum hljóðstyrk í langan tíma kann það að skaða heyrnina."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Viltu nota aðgengisflýtileið?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Þegar flýtileiðin er virk er kveikt á aðgengiseiginleikanum með því að halda báðum hljóðstyrkshnöppunum inni í þrjár sekúndur.\n\n Virkur aðgengiseiginleiki:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Hægt er að skipta um eiginleika í Stillingar &gt; Aðgengi."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Autt"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Breyta flýtileiðum"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Hætta við"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Slökkva á flýtileið"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Nota flýtileið"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Umsnúningur lita"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Kveikja á vinnusniði?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Kveikt verður á vinnuforritum, tilkynningum, gögnum og öðrum eiginleikum vinnusniðsins"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Kveikja"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Þetta forrit var hannað fyrir eldri útgáfu af Android og ekki er víst að það virki eðlilega. Athugaðu hvort uppfærslur séu í boði eða hafðu samband við þróunaraðilann."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Leita að uppfærslu"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Þú ert með ný skilaboð"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Rafhlaðan kann að tæmast áður en hún kemst í hleðslu"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Kveikt á rafhlöðusparnaði til að lengja endingu rafhlöðunnar"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Rafhlöðusparnaður"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Rafhlöðusparnaður verður ekki virkur þar til næst þegar lítil hleðsla er á rafhlöðunni"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Rafhlaðan hefur fengið nægilega hleðslu. Rafhlöðusparnaður verður ekki virkur aftur fyrr en hleðslan verður lítil aftur."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Síminn er með <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> hleðslu"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Hleðsla spjaldtölvunnar er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Tækið er með <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> hleðslu"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Slökkt er á rafhlöðusparnaði. Eiginleikar eru ekki lengur takmarkaðir."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Slökkt á rafhlöðusparnaði. Eiginleikar eru ekki lengur takmarkaðir."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Slökkt á rafhlöðusparnaði"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Síminn er með næga hleðslu. Eiginleikar eru ekki lengur takmarkaðir."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Spjaldtölva er með næga hleðslu. Eiginleikar eru ekki lengur takmarkaðir."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Tæki er með næga hleðslu. Eiginleikar eru ekki lengur takmarkaðir."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Mappa"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android forrit"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Skrá"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 87a1191..387d52e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accedere al calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"inviare e visualizzare SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Archiviazione"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"File e contenuti multimediali"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"accedere a foto, contenuti multimediali e file sul dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"registrare audio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Consente di toccare, far scorrere, pizzicare ed eseguire altri gesti."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gesti con sensore di impronte"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"È in grado di rilevare i gesti compiuti con il sensore di impronte dei dispositivi."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Acquisire screenshot"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Può acquisire uno screenshot del display."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disattivazione o modifica della barra di stato"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ruolo di barra di stato"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vuoi aumentare il volume oltre il livello consigliato?\n\nL\'ascolto ad alto volume per lunghi periodi di tempo potrebbe danneggiare l\'udito."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usare la scorciatoia Accessibilità?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando la scorciatoia è attiva, puoi premere entrambi i pulsanti del volume per tre secondi per avviare una funzione di accessibilità.\n\n Funzione di accessibilità corrente:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puoi cambiare la funzione in Impostazioni &gt; Accessibilità."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Svuota"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifica scorciatoie"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annulla"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Disattiva scorciatoia"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usa scorciatoia"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversione colori"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Attivare il profilo di lavoro?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Le tue app di lavoro, le notifiche, i dati e altri elementi del profilo di lavoro saranno attivati."</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Attiva"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Questa app è stata realizzata per una versione precedente di Android e potrebbe non funzionare correttamente. Prova a verificare la disponibilità di aggiornamenti o contatta lo sviluppatore."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verifica la presenza di aggiornamenti"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"La batteria potrebbe esaurirsi prima della ricarica abituale"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Risparmio energetico attivo per far durare di più la batteria"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Risparmio energetico"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Risparmio energetico non si riattiverà finché la batteria non raggiungerà nuovamente un livello di carica basso"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"La batteria ha raggiunto un livello di carica sufficiente. Risparmio energetico non si riattiverà finché la batteria non raggiungerà nuovamente un livello di carica basso"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Livello di carica del telefono: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Livello di carica del tablet: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Livello di carica del dispositivo: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Il risparmio energetico è disattivato. Funzionalità non più limitate."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Risparmio energetico disattivato. Funzionalità non più limitate."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Risparmio energetico disattivato"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Il telefono ha carica sufficiente. Funzionalità non più limitate."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Il tablet ha carica sufficiente. Funzionalità non più limitate."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Il dispositivo ha carica sufficiente. Funzionalità non più limitate."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Cartella"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Applicazione Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index f4624ba..cf6fa22 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"גישה אל היומן"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏שליחה והצגה של הודעות SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"אחסון"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"גישה לתמונות, למדיה ולקבצים במכשיר שלך"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"מיקרופון"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"הקלטת אודיו"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"יכול להקיש, להחליק, לעשות תנועת צביטה ולבצע תנועות אחרות."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"תנועות של טביעות אצבעות"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"אפשרות לזהות תנועות בזמן נגיעה בחיישן טביעות האצבע של המכשיר."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"השבת או שנה את שורת המצב"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"מאפשר לאפליקציה להשבית את שורת המצב או להוסיף ולהסיר סמלי מערכת."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"להיות שורת הסטטוס"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?\n\nהאזנה בעוצמת קול גבוהה למשכי זמן ממושכים עלולה לפגוע בשמיעה."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"להשתמש בקיצור הדרך לתכונת הנגישות?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"כשקיצור הדרך מופעל, לחיצה על שני לחצני עוצמת השמע למשך שלוש שניות מפעילה את תכונת הנגישות.\n\n תכונת הנגישות המוגדרת כרגע:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n אפשר לשנות את התכונה בקטע \'הגדרות ונגישות\'."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ריק"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"עריכת קיצורי הדרך"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ביטול"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"כבה את קיצור הדרך"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"השתמש בקיצור הדרך"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"היפוך צבעים"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"להפעיל את פרופיל העבודה?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"אפליקציות העבודה, התראות, נתונים ותכונות נוספות של פרופיל העבודה יופעלו"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"הפעל"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏האפליקציה הזו עוצבה לגרסה ישנה יותר של Android וייתכן שלא תפעל כראוי. ניתן לבדוק אם יש עדכונים או ליצור קשר עם המפתח."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"האם יש עדכון חדש?"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"יש לך הודעות חדשות"</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"הסוללה עלולה להתרוקן לפני המועד הרגיל של הטעינה"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"תכונת החיסכון בסוללה הופעלה כדי להאריך את חיי הסוללה"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"חיסכון בסוללה"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"\'חיסכון בסוללה\' יופעל שוב רק כשהסוללה תהיה שוב חלשה"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"רמת הטעינה של הסוללה מספיקה. \'חיסכון בסוללה\' יופעל מחדש רק כשהסוללה תהיה שוב חלשה."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"הטלפון טעון בשיעור <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"הטאבלט טעון בשיעור <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"המכשיר טעון בשיעור <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"\'חיסכון בסוללה\' כבוי. התכונות כבר לא מוגבלות."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"\'חיסכון בסוללה\' כבוי. התכונות כבר לא מוגבלות."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"תיקייה"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"‏אפליקציית Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"קובץ"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 79d9faa..e7f5e85 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"カレンダーへのアクセス"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMSメッセージの送信と表示"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ストレージ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"デバイス内の写真、メディア、ファイルへのアクセス"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"マイク"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"音声の録音"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"タップ、スワイプ、ピンチ、その他の操作を行えます。"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"指紋認証センサーでの操作"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"デバイスの指紋認証センサーで行われた操作をキャプチャできます。"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"ステータスバーの無効化や変更"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ステータスバーの無効化、システムアイコンの追加や削除をアプリに許可します。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ステータスバーへの表示"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"推奨レベルを超えるまで音量を上げますか?\n\n大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ユーザー補助機能のショートカットの使用"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ショートカットが ON の場合、両方の音量ボタンを 3 秒間押し続けるとユーザー補助機能が起動します。\n\n現在のユーザー補助機能:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nユーザー補助機能は [設定] &gt; [ユーザー補助] で変更できます。"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"空"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ショートカットの編集"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"キャンセル"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ショートカットを OFF にする"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ショートカットを使用"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色反転"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"仕事用プロファイルの有効化"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"仕事用のアプリ、通知、データなど、仕事用プロファイルの機能が ON になります"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ON にする"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"このアプリは以前のバージョンの Android 用に作成されており、正常に動作しない可能性があります。アップデートを確認するか、デベロッパーにお問い合わせください。"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"アップデートを確認"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"新着メッセージがあります"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"通常の充電を行う前に電池が切れる可能性があります"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"電池を長持ちさせるため、バッテリー セーバーが有効になりました"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"バッテリー セーバー"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"バッテリー セーバーは、電池残量が再び低下するまで有効に戻りません。"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"電池が十分なレベルまで充電されました。バッテリー セーバーは、電池残量が再び低下するまで有効に戻りません。"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"スマートフォンの電池残量 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"タブレットの電池残量 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"デバイスの電池残量 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"バッテリー セーバーが無効になりました。機能は制限されなくなりました。"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"バッテリー セーバーが無効になりました。機能は制限されなくなりました。"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"フォルダ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android アプリ"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ファイル"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index a0f631e4..5d4a560 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"თქვენს კალენდარზე წვდომა"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS შეტყობინებების გაგზავნა და ნახვა"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"შესანახი სივრცე"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"თქვენს მოწყობილობაზე არსებულ ფოტოებზე, მედიასა და ფაილებზე წვდომა"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"მიკროფონი"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"აუდიოს ჩაწერა"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"შეუძლია შეხება, გადაფურცვლა, მასშტაბირება და სხვა ჟესტების შესრულება."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"თითის ანაბეჭდის ჟესტები"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"შეუძლია აღბეჭდოს მოწყობილობის თითის ანაბეჭდის სენსორზე განხორციელებული ჟესტები."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"სტატუსის ზოლის ჩანაცვლება"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"გსურთ ხმის რეკომენდებულ დონეზე მაღლა აწევა?\n\nხანგრძლივად ხმამაღლა მოსმენით შესაძლოა სმენადობა დაიზიანოთ."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"გსურთ მარტივი წვდომის მალსახმობის გამოყენება?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"მალსახმობის ჩართვის შემთხვევაში, ხმის ორივე ღილაკზე 3 წამის განმავლობაში დაჭერით მარტივი წვდომის ფუნქცია ჩაირთვება.\n\n მარტივი წვდომის ამჟამინდელი ფუნქციაა:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ამ ფუნქციის შეცვლა შეგიძლიათ აქ: პარამეტრები &gt; მარტივი წვდომა."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ცარიელი"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"მალსახმობების რედაქტირება"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"გაუქმება"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"მალსახმობის გამორთვა"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"მალსახმობის გამოყენება"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ფერთა ინვერსია"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"ჩაირთოს სამსახურის პროფილი?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"თქვენი სამსახურის აპები, შეტყობინებები, მონაცემები და სამსახურის პროფილის ყველა სხვა ფუნქცია ჩაირთვება"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ჩართვა"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ეს აპი Android-ის ძველი ვერსიისთვის შეიქმნა და შესაძლოა სათანადოდ არ მუშაობდეს. გადაამოწმეთ განახლებები ან დაუკავშირდით დეველოპერს."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"განახლების შემოწმება"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"თქვენ ახალი შეტყობინებები გაქვთ"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ბატარეა შეიძლება დაჯდეს დატენის ჩვეულ დრომდე"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ბატარეის დამზოგი გააქტიურდა ბატარეის მუშაობის გასახანგრძლივლებლად"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ბატარეის დამზოგი"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ბატარეის დამზოგი ხელახლა არ გააქტიურდება, სანამ ბატარეა ისევ არ დაიცლება"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ბატარეა საკმარისად არის დატენილი. ბატარეის დამზოგი ხელახლა არ გააქტიურდება, სანამ ბატარეა ისევ არ დაიცლება."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ტელეფონი <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> დატენილია"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ტაბლეტი <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> დატენილია"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"მოწყობილობა <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> დატენილია"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ბატარეის დამზოგი გამორთულია. ფუნქციები შეზღუდული აღარ არის."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ბატარეის დამზოგი გამორთულია. ფუნქციები შეზღუდული აღარ არის."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"საქაღალდე"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-ის აპლიკაცია"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ფაილი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index e6562c4..2acbb17 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"күнтізбеге кіру"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS хабарларын жіберу және көру"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Жад"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"құрылғыдағы фотосуреттерге, мультимедиаға және файлдарға қол жеткізу"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"аудио жазу"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Түртуге, сырғытуға, қысуға және басқа қимылдарды орындауға болады."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Саусақ ізі сканеріндегі қимылдар"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Құрылғының саусақ ізі сенсорында орындалған қимылдарды сақтайды."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"күйін көрсету тақтасын өшіру немесе өзгерту"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Қолданбаға күй жолағын өшіруге немесе жүйелік белгішелерді қосуға және жоюға рұқсат береді."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"күй жолағы болу"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дыбыс деңгейін ұсынылған деңгейден көтеру керек пе?\n\nЖоғары дыбыс деңгейінде ұзақ кезеңдер бойы тыңдау есту қабілетіңізге зиян тигізуі мүмкін."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Арнайы мүмкіндік төте жолын пайдалану керек пе?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Бұл төте жол қосулы кезде дыбыс деңгейі түймелерінің екеуін де 3 секунд бойы басқанда арнайы мүмкіндік іске қосылады.\n\n Ағымдағы арнайы мүмкіндік:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Бұл мүмкіндікті \"Параметрлер\" &gt; \"Арнайы мүмкіндіктер\" тармағында өзгертуге болады."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Бос"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Таңбашаларды өзгерту"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Бас тарту"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Төте жолды өшіру"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Төте жолды пайдалану"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстер инверсиясы"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Жұмыс профилі қосылсын ба?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Жұмыс қолданбалары, хабарландырулар, деректер және басқа да жұмыс профильдерінің мүмкіндіктері қосылады"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Қосу"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Қолданба Android жүйесінің ескі нұсқасына арналған және дұрыс жұмыс істемеуі мүмкін. Жаңартылған нұсқаны тексеріңіз немесе әзірлеушіге хабарласыңыз."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңартылған нұсқаны тексеру"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Сізде жаңа хабарлар бар"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Battery Saver іске қосылды"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Battery Saver"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Батарея қуаты азаймайынша, Battery Saver қайта қосылмайды."</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батарея сәйкес деңгейге дейін зарядталды. Батарея қуаты азаймайынша, Battery Saver қайта қосылмайды."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефон батареясының қуат деңгейі: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Планшет батареясының қуат деңгейі: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Құрылғының батарея қуатының деңгейі: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Battery Saver өшірулі. Функцияларға енді шектеу қойылмайды."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Battery Saver өшірілді. Функцияларға енді шектеу қойылмайды."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Қалта"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android қолданбасы"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index e6397ad..0e277ef 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"សារ SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ផ្ញើ និងមើលសារ SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ទំហំ​ផ្ទុក"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ចូលដំណើការរូបភាព មេឌៀ និងឯកសារនៅលើឧបករណ៍របស់អ្នក"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"មីក្រូ​ហ្វូន"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ថតសំឡេង"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"អាចប៉ះ អូស ច្បិច និងធ្វើកាយវិការផ្សេងទៀត"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ចលនា​ស្នាមម្រាមដៃ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"អាចចាប់យក​ចលនា​ដែលធ្វើនៅលើ​នៅលើ​ឧបករណ៍​ចាប់​ស្នាម​ម្រាមដៃ​របស់ឧបករណ៍បាន។"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"បិទ ឬ​កែ​របារ​ស្ថានភាព"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ឲ្យ​កម្មវិធី​បិទ​របារ​ស្ថានភាព ឬ​បន្ថែម និង​លុប​រូប​តំណាង​ប្រព័ន្ធ។"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ធ្វើជារបារស្ថានភាព"</string>
@@ -1612,6 +1617,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"បង្កើន​កម្រិត​សំឡេង​លើស​ពី​កម្រិត​បាន​ផ្ដល់​យោបល់?\n\nការ​ស្ដាប់​នៅ​កម្រិត​សំឡេង​ខ្លាំង​យូរ​អាច​ធ្វើឲ្យ​ខូច​ត្រចៀក។"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ប្រើប្រាស់​ផ្លូវកាត់​ភាព​ងាយស្រួល?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"នៅពេល​ផ្លូវកាត់​នេះបើក ការ​ចុច​ប៊ូតុង​កម្រិត​សំឡេង​ទាំង​ពីរ​ឲ្យ​ជាប់​រយៈពេល​ 3 វិនាទីនឹង​ចាប់ផ្តើម​មុខងារ​ភាពងាយស្រួល។\n\n មុខងារ​ភាពងាយស្រួល​បច្ចុប្បន្ន៖\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n អ្នក​អាច​ផ្លាស់​ប្តូរ​មុខងារ​នេះ​បាន​នៅក្នុង​ការ កំណត់ &gt; ភាព​ងាយស្រួល។"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"លុបទាំងអស់"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"កែ​ផ្លូវកាត់"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"បោះបង់"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"បិទ​ផ្លូវកាត់"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ប្រើប្រាស់​ផ្លូវកាត់"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"បញ្ច្រាស​ពណ៌"</string>
@@ -1847,6 +1855,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"បើក​កម្រង​ព័ត៌មាន​ការ​ងារ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"កម្មវិធី​ការងារ ការ​ជូនដំណឹង ទិន្នន័យ និង​មុខងារ​កម្រង​ព័ត៌មាន​ការងារ​ផ្សេង​ទៀត​របស់អ្នក​នឹង​ត្រូវ​បាន​បើក"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"បើក"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"កម្មវិធី​នេះ​ត្រូវបាន​បង្កើត​ឡើង​សម្រាប់​កំណែ​ប្រព័ន្ធ​ប្រតិបត្តិការ Android ចាស់ ហើយ​វាអាច​ដំណើរការ​ខុសប្រក្រតី។ សូម​សាកល្បង​ពិនិត្យមើល​កំណែ​ថ្មី ឬ​ទាក់ទង​ទៅអ្នក​អភិវឌ្ឍន៍។"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"រក​មើល​កំណែ​ថ្មី"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"អ្នកមានសារថ្មី"</string>
@@ -1957,13 +1969,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ថ្ម​អាច​នឹង​អស់ មុនពេល​សាកថ្មធម្មតា"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បាន​បើក​ដំណើរការកម្មវិធី​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"កម្មវិធីសន្សំថ្ម"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"កម្មវិធី​សន្សំ​ថ្មនឹង​មិន​បើក​ដំណើរការឡើងវិញ​ទេ រហូតទាល់តែ​ថ្មមានកម្រិតទាប​ម្ដងទៀត"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ថ្ម​បាន​សាក​ដល់​កម្រិត​គ្រប់គ្រាន់ហើយ។ កម្មវិធី​សន្សំ​ថ្មនឹង​មិន​បើក​ដំណើរការ​ឡើងវិញទេ រហូតទាល់តែ​ថ្មមានកម្រិតទាប​ម្ដងទៀត។"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"បាន​សាកថ្មទូរសព្ទ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"បាន​សាកថ្មថេប្លេត <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"បានសាកថ្មឧបករណ៍ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"កម្មវិធី​សន្សំ​ថ្ម​បាន​បិទ។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"បានបិទកម្មវិធី​សន្សំ​ថ្ម។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ថត"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"​កម្មវិធី Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ឯកសារ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 22edcae..50b1bba 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ನಿರ್ವಹಿಸಲು"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ಸಂಗ್ರಹಣೆ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ಸಾಧನದಲ್ಲಿ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ ಮತ್ತು ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ಮೈಕ್ರೋಫೋನ್‌"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ಟ್ಯಾಪ್ ಮಾಡಬಹುದು, ಸ್ವೈಪ್ ಮಾಡಬಹುದು, ಪಿಂಚ್ ಮಾಡಬಹುದು ಮತ್ತು ಇತರ ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಮಾಡಬಹುದು."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಗೆಶ್ಚರ್‌ಗಳು"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ಸಾಧನದ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌ನಲ್ಲಿ ನಡೆಸಿದ ಗೆಶ್ಚರ್‌ಗಳನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇಲ್ಲವೇ ಮಾರ್ಪಡಿಸಿ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಮತ್ತು ಸಿಸ್ಟಂ ಐಕಾನ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಾಗಿರಲು"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ವಾಲ್ಯೂಮ್‌ ಅನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾದ ಮಟ್ಟಕ್ಕಿಂತಲೂ ಹೆಚ್ಚು ಮಾಡುವುದೇ?\n\nದೀರ್ಘ ಅವಧಿಯವರೆಗೆ ಹೆಚ್ಚಿನ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಆಲಿಸುವುದರಿಂದ ನಿಮ್ಮ ಆಲಿಸುವಿಕೆ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟು ಮಾಡಬಹುದು."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸುವುದೇ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ಶಾರ್ಟ್‌ಕಟ್ ಆನ್ ಆಗಿರುವಾಗ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯ ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳನ್ನು ನೀವು 3 ಸೆಕೆಂಡುಗಳ ಕಾಲ ಒತ್ತಬೇಕು.\n\nಪ್ರಸ್ತುತ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯ: \n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಪ್ರವೇಶಿಸುವಿಕೆಯಲ್ಲಿ ನೀವು ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ಖಾಲಿ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ಶಾರ್ಟ್‌ಕಟ್‌‍ಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ಶಾರ್ಟ್‌ಕಟ್‌ ಆಫ್ ಮಾಡಿ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸಿ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ಬಣ್ಣ ವಿಲೋಮ"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಆನ್ ಮಾಡುವುದೇ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"ನಿಮ್ಮ ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ಅಧಿಸೂಚನೆಗಳು, ಡೇಟಾ ಮತ್ತು ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನ ಇತರ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆನ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ಆನ್‌ ಮಾಡಿ"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗೆ ರಚಿಸಲಾಗಿದೆ ಮತ್ತು ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡದಿರಬಹುದು. ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಅಥವಾ ಡೆವಲಪರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"ನೀವು ಹೊಸ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವಿರಿ"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ಚಾರ್ಜ್‌ಗೆ ಮೊದಲೆ ಬ್ಯಾಟರಿ ಮುಗಿದು ಬಿಡಬಹುದು"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ಬ್ಯಾಟರಿ ಅವಧಿ ಹೆಚ್ಚಿಸಲು ಬ್ಯಾಟರಿ ಸೇವರ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ಬ್ಯಾಟರಿ ಸೇವರ್"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ಇನ್ನೊಮ್ಮೆ ಬ್ಯಾಟರಿ ಕಡಿಮೆಯಾಗುವವರೆಗೂ ಬ್ಯಾಟರಿ ಸೇವರ್ ಮರುಸಕ್ರಿಯವಾಗುವುದಿಲ್ಲ"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ಬ್ಯಾಟರಿಯನ್ನು ಬೇಕಾಗಿರುವಷ್ಟು ಮಟ್ಟಕ್ಕೆ ಚಾರ್ಜ್ ಮಾಡಲಾಗಿದೆ. ಇನ್ನೊಮ್ಮೆ ಬ್ಯಾಟರಿ ಕಡಿಮೆಯಾಗುವವರೆಗೂ ಬ್ಯಾಟರಿ ಸೇವರ್ ಮರುಸಕ್ರಿಯವಾಗುವುದಿಲ್ಲ."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ಫೋನ್ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ಟ್ಯಾಬ್ಲೆಟ್ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ಸಾಧನ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಆಫ್ ಆಗಿದೆ. ಇನ್ನು ಮುಂದೆ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗುವುದಿಲ್ಲ."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಅನ್ನು ಆಫ್ ಮಾಡಲಾಗಿದೆ. ಇನ್ನು ಮುಂದೆ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ಫೋಲ್ಡರ್"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ಆ್ಯಪ್‌"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ಫೈಲ್"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index df26c4e..7e12490 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"캘린더에 액세스"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS 메시지 전송 및 보기"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"저장용량"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"기기 사진, 미디어, 파일 액세스"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"마이크"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"오디오 녹음"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"탭, 스와이프, 확대/축소 및 기타 동작을 실행할 수 있습니다."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"지문 동작"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"기기 지문 센서에서 동작을 캡처합니다."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"상태 표시줄 사용 중지 또는 수정"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"앱이 상태 표시줄을 사용중지하거나 시스템 아이콘을 추가 및 제거할 수 있도록 허용합니다."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"상태 표시줄에 위치"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"권장 수준 이상으로 볼륨을 높이시겠습니까?\n\n높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"접근성 단축키를 사용하시겠습니까?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"단축키가 사용 설정된 경우 두 개의 볼륨 버튼을 3초간 누르면 접근성 기능이 시작됩니다.\n\n 현재 접근성 기능:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n \'설정 &gt; 접근성\'에서 기능을 변경할 수 있습니다."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"비우기"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"단축키 수정"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"취소"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"단축키 사용 중지"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"단축키 사용"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"색상 반전"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"직장 프로필을 사용 설정하시겠어요?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"업무용 앱, 알림, 데이터 및 기타 직장 프로필 기능이 사용 설정됩니다."</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"사용 설정"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"이 앱은 Android 이전 버전에 맞게 개발되었기 때문에 제대로 작동하지 않을 수 있습니다. 업데이트를 확인하거나 개발자에게 문의하세요."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"업데이트 확인"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"새 메시지 있음"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"평소에 충전하는 시간 전에 배터리가 소진될 수 있습니다."</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"배터리 수명을 연장하기 위해 배터리 세이버가 활성화되었습니다."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"절전 모드"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"배터리가 다시 부족해지기 전까지 절전 모드가 재활성화되지 않음"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"배터리가 충분히 충전되었습니다. 배터리가 다시 부족해지기 전까지는 절전 모드가 재활성화되지 않습니다."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"휴대전화 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> 충전됨"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"태블릿 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> 충전됨"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"기기 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> 충전됨"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"절전 모드가 꺼져 있습니다. 기능이 더 이상 제한되지 않습니다."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"절전 모드가 사용 중지되었습니다. 기능이 더 이상 제한되지 않습니다."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"폴더"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android 애플리케이션"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"파일"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index adcc4c1..c887c34 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"жылнаамаңызды пайдалануу"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Сактагыч"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"түзмөгүңүздөгү сүрөттөрдү жана башка мультимедиа файлдарын пайдаланууга"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"аудио жаздыруу"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Таптап, серпип, чымчып жана башка жаңсоолорду аткара алат."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Манжа изинин жаңсоолору"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Түзмөктөгү манжа изинин сенсорунда жасалган жаңсоолорду жаздырып алат."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"абал тилкесин өчүрүү же өзгөртүү"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Колдонмого абал тилкесин өчүрүү же тутум сүрөтчөлөрүн кошуу же алып салуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"абал тилкесинин милдетин аткаруу"</string>
@@ -1395,7 +1400,7 @@
     <string name="ime_action_default" msgid="8265027027659800121">"Аткаруу"</string>
     <string name="dial_number_using" msgid="6060769078933953531">"<xliff:g id="NUMBER">%s</xliff:g> менен\nномерди терүү"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"<xliff:g id="NUMBER">%s</xliff:g> менен\nбайланыш түзүү"</string>
-    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Төмөнкү бир же бир нече колдонмо каттоо эсебиңизге азыр жана кийинчерээк кирүү мүмкүнчүлүгүн сурап жатат."</string>
+    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Төмөнкү бир же бир нече колдонмо аккаунтуңузга азыр жана кийинчерээк кирүү мүмкүнчүлүгүн сурап жатат."</string>
     <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Бул өтүнүчкө уруксат бересизби?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"Жетки талабы"</string>
     <string name="allow" msgid="6195617008611933762">"Уруксат берүү"</string>
@@ -1602,14 +1607,17 @@
     <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">"Android TV түзмөгүңүздүн кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Android TV түзмөгүңүз эми демейки жөндөөлөргө кайтарылат."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Сиз телефонуңузду <xliff:g id="NUMBER">%d</xliff:g> жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Телефон баштапкы абалына кайтарылат."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес көрсөттүңүз. <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес көрсөтүлгөндөн кийин, планшетиңиздин кулпусун ачуу үчүн Google каттоо эсебиңизге кирүүгө туура келет.\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> жолу туура эмес көрсөтүлгөндөн кийин, планшетиңиздин кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\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> жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google каттоо эсебиңизге кирүүгө туура келет.\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> жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\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>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн, ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең үч секунддай кое бербей басып туруңуз.\n\n Учурдагы атайын мүмкүнчүлүктөрдүн жөндөөлөрү:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nЖөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнөн өзгөртө аласыз."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Бошотуу"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Кыска жолдорду түзөтүү"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Жокко чыгаруу"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Кыска жолду өчүрүү"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Кыска жолду колдонуу"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстү инверсиялоо"</string>
@@ -1843,8 +1851,12 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> колдонмосу учурда жеткиликсиз. Анын жеткиликтүүлүгү <xliff:g id="APP_NAME_1">%2$s</xliff:g> тарабынан башкарылат."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"Кеңири маалымат"</string>
     <string name="work_mode_off_title" msgid="5503291976647976560">"Жумуш профили күйгүзүлсүнбү?"</string>
-    <string name="work_mode_off_message" msgid="8417484421098563803">"Жумуш колдонмолоруңуз, эскертмелериңиз, дайындарыңыз жана жумуш профилинин башка функциялары күйгүзүлөт."</string>
+    <string name="work_mode_off_message" msgid="8417484421098563803">"Жумуш колдонмолоруңуз, эскертмелериңиз, дайын-даректериңиз жана жумуш профилинин башка функциялары күйгүзүлөт."</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Күйгүзүү"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Бул колдонмо Android\'дин эски версиясы үчүн иштеп чыгарылган, андыктан туура эмес иштеши мүмкүн. Жаңыртууларды издеп көрүңүз же иштеп чыгуучуга кайрылыңыз."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңыртууну издөө"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Сизге жаңы билдирүүлөр келди"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея кубаттоого чейин отуруп калышы мүмкүн"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батареянын отуруп калбашы үчүн Батареяны үнөмдөгүч режими иштетилди"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Батареяны үнөмдөгүч"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Батареяны үнөмдөгүч батарея кайра азаймайынча күйгүзүлбөйт"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батарея жетиштүү деңгээлге чейин кубатталды. Батареяны үнөмдөгүч батарея кайра азайганча чейин күйгүзүлбөйт."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефон <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> кубатталды"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Планшет <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> кубатталды"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Түзмөк <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> кубатталды"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Батареяны үнөмдөгүч өчүк. Функцияны колдоно берсеңиз болот."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Батареяны үнөмдөгүч режими өчүрүлдү. Функцияны колдоно берсеңиз болот."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android колдонмосу"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 230f2b5..52674c0 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ເຂົ້າ​ຫາ​ປະ​ຕິ​ທິນ​ຂອງ​ທ່ານ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ສົ່ງ ແລະ​ເບິ່ງ​ຂໍ້​ຄວາມ SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ເຂົ້າເຖິງຮູບຖ່າຍ, ສື່ ແລະໄຟລ໌ຢູ່ເທິງອຸປະກອນຂອງທ່ານ"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ໄມໂຄຣໂຟນ"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ບັນທຶກສຽງ"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ສາມາດແຕະ, ປັດນີ້ວມື, ຢິບນິ້ວມື ແລະ ດຳເນີນທ່າທາງອື່ນ."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ທ່າທາງລາຍນິ້ວມື"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ສາມາດບັນທຶກທ່າທາງທີ່ເກີດຂຶ້ນໃນອຸປະກອນເຊັນເຊີລາຍນິ້ວມືໄດ້."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ເປັນ​ແຖບ​ສະ​ຖາ​ນະ"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ເພີ່ມ​ລະ​ດັບ​ສຽງ​ໃຫ້​ເກີນກວ່າ​ລະ​ດັບ​ທີ່​ແນະ​ນຳ​ບໍ?\n\n​ການ​ຮັບ​ຟັງ​ສຽງ​ໃນ​ລະ​ດັບ​ທີ່​ສູງ​ເປັນ​ໄລ​ຍະ​ເວ​ລາ​ດົນ​​ອາດ​ເຮັດ​ໃຫ້​ການ​ຟັງ​ຂອງ​ທ່ານ​ມີ​ບັນ​ຫາ​ໄດ້."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ໃຊ້ປຸ່ມລັດການຊ່ວຍເຂົ້າເຖິງບໍ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ເມື່ອເປີດໃຊ້ປຸ່ມລັດແລ້ວ, ໃຫ້ກົດປຸ່ມສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີເພື່ອເລີ່ມຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງ.\n\n ຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງປັດຈຸບັນ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ທ່ານສາມາດປ່ຽນຄຸນສົມບັດໄດ້ໃນການຕັ້ງຄ່າ &gt; ການຊ່ວຍເຂົ້າເຖິງ."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ຫວ່າງເປົ່າ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ແກ້ໄຂທາງລັດ"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ຍົກເລີກ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ປິດປຸ່ມລັດ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ໃຊ້ປຸ່ມລັດ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ການປີ້ນສີ"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"ເປີດໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກບໍ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"ແອັບວຽກຂອງທ່ານ, ການແຈ້ງເຕືອນ, ຂໍ້ມູນ ແລະ ຄຸນສົມບັດໂປຣໄຟລ໌ວຽກຈະຖືກເປີດໃຊ້"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ເປີດ​"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ແອັບນີ້ຖືກສ້າງຂຶ້ນສຳລັບ Android ເວີຊັນທີ່ເກົ່າກວ່າ ແລະ ອາດເຮັດວຽກໄດ້ບໍ່ປົກກະຕິ. ໃຫ້ລອງກວດສອບເບິ່ງອັບເດດ ຫຼື ຕິດຕໍ່ຜູ້ພັດທະນາ."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ກວດເບິ່ງອັບເດດ"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"ທ່ານມີຂໍ້ຄວາມໃໝ່"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ແບັດເຕີຣີອາດໝົດກ່ອນການສາກຕາມປົກກະຕິ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ເປີດຕົວປະຢັດແບັດເຕີຣີເພື່ອຂະຫຍາຍອາຍຸແບັດເຕີຣີ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ຕົວປະຢັດແບັດເຕີຣີ"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ຈະບໍ່ມີການເປີດໃຊ້ຕົວປະຢັດແບັດເຕີຣີຄືນໃໝ່ຈົນກວ່າແບັດເຕີຣີຈະເຫຼືອໜ້ອຍອີກເທື່ອໜຶ່ງ"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ສາກແບັດເຕີຣີຮອດລະດັບທີ່ພຽງພໍແລ້ວ. ຕົວປະຢັດແບັດເຕີຣີຈະບໍ່ເປີດໃຊ້ຄືນໃໝ່ຈົນກວ່າແບັດເຕີຣີຈະເຫຼືອໜ້ອຍກີເທື່ອໜຶ່ງ."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ສາກໂທລະສັບແລ້ວ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ສາກແທັບເລັດແລ້ວ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ສາກອຸປະກອນແລ້ວ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ຕົວປະຢັດແບັດເຕີຣີປິດຢູ່. ບໍ່ມີການຈຳກັດຄຸນສົມບັດອີກຕໍ່ໄປແລ້ວ."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ປິດຕົວປະຢັດແບັດເຕີຣີແລ້ວ. ບໍ່ມີການຈຳກັດຄຸນສົມບັດອີກຕໍ່ໄປແລ້ວ."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ໂຟນເດີ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"ແອັບພລິເຄຊັນ Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ໄຟລ໌"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 5a85f48..5097d45 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -293,7 +293,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pasiekti kalendorių"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"siųsti ir peržiūrėti SMS pranešimus"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Saugykla"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Failai ir medija"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"pasiekti nuotraukas, mediją ir failus įrenginyje"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonas"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"įrašyti garso įrašą"</string>
@@ -319,6 +319,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Galima paliesti, perbraukti, suimti ir atlikti kitus veiksmus gestais."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Piršto antspaudo gestai"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Gali užfiksuoti gestus, atliktus naudojant įrenginio piršto antspaudo jutiklį."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekrano kopijos kūrimas"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Galima sukurti vaizdo ekrano kopiją."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"išjungti ar keisti būsenos juostą"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"būti būsenos juosta"</string>
@@ -1654,6 +1656,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Padidinti garsą daugiau nei rekomenduojamas lygis?\n\nIlgai klausydami dideliu garsu galite pažeisti klausą."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Naudoti spartųjį pritaikymo neįgaliesiems klavišą?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kai spartusis klavišas įjungtas, spaudžiant abu garsumo mygtukus 3 sekundes bus paleista pritaikymo neįgaliesiems funkcija.\n\n Dabartinė pritaikymo neįgaliesiems funkcija:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>„\n“\n Funkciją galite pakeisti skiltyje „Nustatymai“ &gt; „Pritaikymas neįgaliesiems“."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Išvalyti"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redaguoti sparčiuosius klavišus"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Atšaukti"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Išjungti spartųjį klavišą"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Naudoti spartųjį klavišą"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Spalvų inversija"</string>
@@ -1909,6 +1914,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Įjungti darbo profilį?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Darbo programos, pranešimai, duomenys ir kitos darbo profilio funkcijos bus išjungtos"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Įjungti"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Programa nepasiekiama."</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu nepasiekiama."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ši programa sukurta naudoti senesnės versijos sistemoje „Android“ ir gali tinkamai neveikti. Pabandykite patikrinti, ar yra naujinių, arba susisiekite su kūrėju."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tikrinti, ar yra naujinių"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Turite naujų pranešimų"</string>
@@ -2021,13 +2028,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumuliatoriaus energija gali išsekti prieš įprastą įkrovimą"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akumuliatoriaus tausojimo priemonė suaktyvinta, kad akumuliatorius veiktų ilgiau"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akumuliatoriaus tausojimo priemonė"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Akumuliatoriaus tausojimo priemonė nebus iš naujo suaktyvinta, kol akumuliatorius vėl beveik išseks"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Pasiektas tinkamas akumuliatoriaus įkrovimo lygis. Akumuliatoriaus tausojimo priemonė nebus iš naujo suaktyvinta, kol akumuliatorius vėl beveik išseks."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefono įkrovimo lygis: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Planšetinio kompiuterio įkrovimo lygis: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Įrenginio įkrovimo lygis: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Akumuliatoriaus tausojimo priemonė išjungta. Funkcijos neberibojamos."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Akumuliatoriaus tausojimo priemonė išjungta. Funkcijos neberibojamos."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akumuliatoriaus tausojimo priemonė išjungta"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonas pakankamai įkrautas. Funkcijos neberibojamos."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Planšetinis kompiuteris pakankamai įkrautas. Funkcijos neberibojamos."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Įrenginys pakankamai įkrautas. Funkcijos neberibojamos."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Aplankas"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"„Android“ programa"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Failas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 17c0c17..7d11634f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -290,7 +290,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"piekļūt jūsu kalendāram"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Īsziņas"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sūtīt un skatīt īsziņas"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Krātuve"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"piekļūt fotoattēliem, multividei un failiem jūsu ierīcē"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofons"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ierakstīt audio"</string>
@@ -316,6 +317,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Atbalsta pieskaršanos, vilkšanu, savilkšanu un citus žestus."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Pirksta nospieduma žesti"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Var uztvert žestus ierīces pirksta nospieduma sensorā."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"atspējot vai pārveidot statusa joslu"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ļauj lietotnei atspējot statusa joslu vai pievienot un noņemt sistēmas ikonas."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Būt par statusa joslu"</string>
@@ -1632,6 +1637,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vai palielināt skaļumu virs ieteicamā līmeņa?\n\nIlgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vai izmantot pieejamības saīsni?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Ja saīsne ir iespējota, vienlaikus nospiežot abas skaļuma regulēšanas pogas un trīs sekundes turot tās, tiks palaista pieejamības funkcija.\n\n Pašreiz iestatītā pieejamības funkcija:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Šo funkciju var mainīt sadaļā Iestatījumi &gt; Pieejamība."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Notīrīt"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Rediģēt īsinājumtaustiņus"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Atcelt"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Izslēgt saīsni"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Izmantot saīsni"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Krāsu inversija"</string>
@@ -1877,6 +1885,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Vai ieslēgt darba profilu?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Tiks ieslēgtas jūsu darba lietotnes, paziņojumi, dati un citas darba profila funkcijas."</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ieslēgt"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Šī lietotne tika izstrādāta vecākai Android versijai un var nedarboties pareizi. Meklējiet atjauninājumus vai sazinieties ar izstrādātāju."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Meklēt atjauninājumu"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Jums ir jaunas īsziņas."</string>
@@ -1988,13 +2000,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumulators var izlādēties pirms parastā uzlādes laika"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Aktivizēts akumulatora jaudas taupīšanas režīms, lai palielinātu akumulatora darbības ilgumu"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akumulatora jaudas taupīšanas režīms"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Akumulatora jaudas taupīšanas režīms tiks atkārtoti aktivizēts tikai tad, kad akumulatora uzlādes līmenis atkal būs zems"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Akumulatora uzlādes līmenis ir pietiekams. Akumulatora jaudas taupīšanas režīms tiks atkārtoti aktivizēts tikai tad, kad akumulatora uzlādes līmenis atkal būs zems."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Tālruņa uzlādes līmenis ir <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Planšetdatora uzlādes līmenis ir <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Ierīces uzlādes līmenis ir <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Akumulatora jaudas taupīšanas režīms ir izslēgts. Funkcijas vairs netiek ierobežotas."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Akumulatora jaudas taupīšanas režīms ir izslēgts. Funkcijas vairs netiek ierobežotas."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Mape"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android lietojumprogramma"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fails"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 2898129..72048b5 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"пристапува до календарот"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"испраќа и прикажува SMS-пораки"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Капацитет"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Датотеки и аудиовизуелни содржини"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"пристапува до фотографии, аудио-видео и датотеки на уредот"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима аудио"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Може да допрете, повлечете, штипнете и да користите други движења."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Движења за отпечатоци"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да сними движења што се направени на сензорот за отпечатоци на уредот."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Правење слика од екранот"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да направи слика од екранот."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"оневозможи или измени статусна лента"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозволува апликацијата да ја оневозможи статусната лента или да додава или отстранува системски икони."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"да стане статусна лента"</string>
@@ -1454,7 +1456,7 @@
     <string name="sync_really_delete" msgid="5657871730315579051">"Избриши ги ставките"</string>
     <string name="sync_undo_deletes" msgid="5786033331266418896">"Врати ги избришаните"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"Не прави ништо засега"</string>
-    <string name="choose_account_label" msgid="5557833752759831548">"Избери сметка"</string>
+    <string name="choose_account_label" msgid="5557833752759831548">"Изберете сметка"</string>
     <string name="add_account_label" msgid="4067610644298737417">"Додај сметка"</string>
     <string name="add_account_button_label" msgid="322390749416414097">"Додај сметка"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Зголеми"</string>
@@ -1612,6 +1614,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да го зголемиме звукот над препорачаното ниво?\n\nСлушањето звуци со голема јачина подолги периоди може да ви го оштети сетилото за слух."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Да се користи кратенка за „Пристапност“?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Кога е вклучена кратенката, ако ги притиснете двете копчиња за јачина на звук во времетраење од 3 секунди, ќе се стартува функција на пристапност.\n\n Тековна функција на пристапност:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Функцијата може да ја промените во „Поставки“ &gt; „Пристапност“."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Испразни"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Изменете ги кратенките"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Откажи"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Исклучи ја кратенката"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи кратенка"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија на бои"</string>
@@ -1847,6 +1852,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Да се вклучи работниот профил?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Вашите работни апликации, известувања, податоци и други функции на работниот профил ќе бидат вклучени"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Вклучи"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Апликацијата не е достапна"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> не е достапна во моментов."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Апликацијава е создадена за постара верзија на Android и може да не функционира правилно. Проверете за ажурирања или контактирајте со програмерот."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за ажурирање"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови пораки"</string>
@@ -1957,13 +1964,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батеријата може да се потроши пред вообичаеното време за полнење"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Активиран е „Штедачот на батерија“ за да се продолжи траењето на батеријата"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Штедач на батерија"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Штедачот на батерија нема да се реактивира додека батеријата не се потроши до одредено ниво повторно"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батеријата е доволно полна. Штедачот на батерија нема да се реактивира додека батеријата не се потроши до одредено ниво повторно."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефонот е наполнет <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Таблетот е наполнет <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Уредот е наполнет <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Штедачот на батерија е исклучен. Функциите веќе не се ограничени."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Штедачот на батерија е исклучен. Функциите веќе не се ограничени."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Штедачот на батерија е исклучен"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Телефонот е доволно полн. Функциите веќе не се ограничени."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Таблетот е доволно полн. Функциите веќе не се ограничени."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Уредот е доволно полн. Функциите веќе не се ограничени."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Апликација за Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Датотека"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 1abf88d..b0bbb67 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ്സ് ചെയ്യുക"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS സന്ദേശങ്ങൾ അയയ്‌ക്കുകയും കാണുകയും ചെയ്യുക"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"സ്റ്റോറേജ്"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"നിങ്ങളുടെ ഉപകരണത്തിലെ ഫോട്ടോകളും മീഡിയയും ഫയലുകളും ആക്സസ് ചെയ്യുക"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"മൈക്രോഫോണ്‍"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ടാപ്പുചെയ്യാനോ സ്വൈപ്പുചെയ്യാനോ പിഞ്ചുചെയ്യാനോ മറ്റ് ജെസ്‌റ്ററുകൾ നിർവഹിക്കാനോ കഴിയും."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ഫിംഗർപ്രിന്റ് ജെസ്‌റ്ററുകൾ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ഉപകരണത്തിന്റെ ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെയ്‌ത ജെസ്‌റ്ററുകൾ ക്യാപ്‌ചർ ചെയ്യാനാകും."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"സ്റ്റാറ്റസ് ബാർ പ്രവർത്തനരഹിതമാക്കുക അല്ലെങ്കിൽ പരിഷ്‌ക്കരിക്കുക"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"നില ബാർ പ്രവർത്തരഹിതമാക്കുന്നതിന് അല്ലെങ്കിൽ സിസ്‌റ്റം ഐക്കണുകൾ ചേർക്കുന്നതിനും നീക്കംചെയ്യുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"സ്റ്റാറ്റസ് ബാർ ആയിരിക്കുക"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"മുകളിൽക്കൊടുത്തിരിക്കുന്ന ശുപാർശചെയ്‌ത ലെവലിലേക്ക് വോളിയം വർദ്ധിപ്പിക്കണോ?\n\nഉയർന്ന വോളിയത്തിൽ ദീർഘനേരം കേൾക്കുന്നത് നിങ്ങളുടെ ശ്രവണ ശേഷിയെ ദോഷകരമായി ബാധിക്കാം."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ഉപയോഗസഹായി കുറുക്കുവഴി ഉപയോഗിക്കണോ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"കുറുക്കുവഴി ഓണാണെങ്കിൽ, രണ്ട് വോളിയം ബട്ടണുകളും 3 സെക്കൻഡ് നേരത്തേക്ക് അമർത്തുന്നത് ഉപയോഗസഹായി ഫീച്ചർ ആരംഭിക്കും.\n\n നിലവിലെ  ഉപയോഗസഹായി ഫീച്ചർ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ക്രമീകരണം &gt; ഉപയോഗസഹായി എന്നതിൽ ഏത് സമയത്തും നിങ്ങൾക്ക് ഫീച്ചർ മാറ്റാവുന്നതാണ്."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ശൂന്യം"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"കുറുക്കുവഴികൾ തിരുത്തുക"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"റദ്ദാക്കുക"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"കുറുക്കുവഴി ‌ഓഫാക്കുക"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"കുറുക്കുവഴി ഉപയോഗിക്കുക"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"ഔദ്യോഗിക പ്രൊഫൈൽ ഓണാക്കണോ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ, അറിയിപ്പുകൾ, ഡാറ്റ, മറ്റ് ഔദ്യോഗിക പ്രൊഫൈൽ ഫീച്ചറുകൾ എന്നിവ ഓണാക്കും"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ഓണാക്കുക"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ഈ ആപ്പ് Android-ന്റെ പഴയ പതിപ്പിനായി നിർമ്മിച്ചിരിക്കുന്നതിനാൽ ശരിയായി പ്രവർത്തിച്ചേക്കില്ല. അപ്‌ഡേറ്റിനായി പരിശോധിക്കുക, അല്ലെങ്കിൽ ഡെവലപ്പറുമായി ബന്ധപ്പെടുക."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"അപ്‌ഡേറ്റിനായി പരിശോധിക്കുക"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"നിങ്ങൾക്ക് പുതിയ സന്ദേശങ്ങൾ ഉണ്ട്"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"സാധാരണയുള്ളതിലും നേരത്തെ ബാറ്ററിയുടെ ചാർജ് തീർന്നേക്കാം"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ബാറ്ററി ലൈഫ് വര്‍ദ്ധിപ്പിക്കാൻ, ബാറ്ററി ലാഭിക്കൽ സജീവമാക്കി"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ബാറ്ററി ലാഭിക്കൽ"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ബാറ്ററി ചാർജ് വീണ്ടും കുറയുന്നത് വരെ ബാറ്ററി ലാഭിക്കൽ പിന്നെയും സജീവമാവുകയില്ല"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"മതിയായ നില വരെ ബാറ്ററി ചാർജായി. വീണ്ടും ബാറ്ററി ചാർജ് കുറയുന്നത് വരെ ബാറ്ററി ലാഭിക്കൽ പിന്നെയും സജീവമാവുകയില്ല."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ഫോൺ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ചാർജായി"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ടാബ്‌ലെറ്റ് <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ചാർജായി"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ഉപകരണം <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ചാർജായി"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ബാറ്ററി ലാഭിക്കൽ ഓഫാണ്. ഫീച്ചറുകൾക്ക് ഇനിമുതൽ നിയന്ത്രണമില്ല."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ബാറ്ററി ലാഭിക്കൽ ഓഫാക്കി. ഫീച്ചറുകൾക്ക് ഇനിമുതൽ നിയന്ത്രണമില്ല."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ഫോള്‍ഡര്‍"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ആപ്പ്"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ഫയൽ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 0f17c00..205df27 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Хуанли руу хандах"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Мессеж"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS мессежийг илгээх, харах"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Хадгалах сан"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"Tөхөөрөмж дээрх зураг, медиа болон файлд хандалт хийх"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"дуу хураах"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Товших, шудрах, жижигрүүлэх болон бусад зангааг хийх боломжтой."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Хурууны хээний зангаа"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Төхөөрөмжийн хурууны хээ мэдрэгчид зангасан зангааг танина."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"статусын хэсэг болох"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дууг санал болгосноос чанга болгож өсгөх үү?\n\nУрт хугацаанд чанга хөгжим сонсох нь таны сонсголыг муутгаж болно."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Хүртээмжийн товчлолыг ашиглах уу?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Товчлолыг асаасан үед дуун товчлуурыг 3 секунд дарснаар хүртээмжийн онцлогийг эхлүүлнэ.\n\n Одоогийн хүртээмжийн онцлог:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Онцлогийг Тохиргоо &gt; Хүртээмж хэсэгт өөрчлөх боломжтой."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Хоосон"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Товчлолуудыг засах"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Болих"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Товчлолыг унтраах"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Товчлол ашиглах"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Өнгө хувиргалт"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ажлын профайлыг асаах уу?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Таны ажлын апп, мэдэгдэл, өгөгдөл болон бусад ажлын профайлын онцлогийг асаана"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Асаах"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Энэ аппыг Андройдын хуучин хувилбарт зориулсан бөгөөд буруу ажиллаж болзошгүй. Шинэчлэлтийг шалгаж эсвэл хөгжүүлэгчтэй холбогдоно уу."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ зурвасууд байна"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарей ихэвчлэн цэнэглэдэг хугацаанаас өмнө дуусаж болзошгүй"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгчийг идэвхжүүллээ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Батарей хэмнэгч"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Батарей хэмнэгч батарейг дахин багасах хүртэл дахин идэвхжихгүй"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батарейг хангалттай түвшинд цэнэглэлээ. Батарей хэмнэгч батарейг дахин багасах хүртэл дахин идэвхжихгүй."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Утсыг <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> цэнэглэсэн байна"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Таблетыг <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> цэнэглэсэн"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Төхөөрөмжийг <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> цэнэглэсэн байна"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Батарей хэмнэгч унтраалттай байна. Онцлогуудыг хязгаарлахаа больсон."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Батарей хэмнэгчийг унтраасан байна. Онцлогуудыг хязгаарлахаа больсон."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Фолдер"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Андройд апп"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index fa8cbb0..b27e1c9 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"आपल्या कॅलेंडरवर प्रवेश"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS मेसेज पाठवणे आणि पाहणे हे"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"स्टोरेज"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"तुमच्या डिव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अ‍ॅक्सेस"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"मायक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडिओ रेकॉर्ड"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"टॅप, स्वाइप, पिंच आणि इतर जेश्चर करू शकते."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"फिंगरप्रिंट जेश्चर"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिव्‍हाइसच्‍या फिंगरप्रिंट सेंन्सरवरील जेश्चर कॅप्‍चर करू शकते."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार होऊ द्या"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"शिफारस केलेल्‍या पातळीच्या वर आवाज वाढवायचा?\n\nउच्च आवाजात दीर्घ काळ ऐकण्‍याने आपल्‍या श्रवणशक्तीची हानी होऊ शकते."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"प्रवेशयोग्यता शॉर्टकट वापरायचा?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"शॉर्टकट चालू असताना, दोन्ही आवाज बटणे 3 सेकंद दाबल्याने प्रवेशयोग्यता वैशिष्ट्य सुरू होईल.\n\n वर्तमान प्रवेशयोग्यता वैशिष्ट्य:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n तुम्ही सेटिंग्ज &gt; प्रवेशयोग्यता मध्ये वैशिष्ट्य बदलू शकता."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"रिकामे करा"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"शॉर्टकट संपादित करा"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"रद्द करा"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"शॉर्टकट बंद करा"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट वापरा"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रंगांची उलटापालट"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"कार्य प्रोफाइल चालू ठेवायची?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"तुमची कार्य अ‍ॅप्स, सूचना, डेटा आणि अन्य कार्य प्रोफाइल वैशिष्ट्ये चालू केली जातील"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"चालू करा"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"हे अ‍ॅप Android च्या जुन्या आवृत्ती साठी तयार करण्यात आले होते आणि योग्यरितीने कार्य करू शकणार नाही. अपडेट आहेत का ते तपासून पाहा, किंवा डेव्हलपरशी संपर्क साधण्याचा प्रयत्न करा."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अपडेट आहे का ते तपासा"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"आपल्याकडे नवीन मेसेज आहेत"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"चार्जिंगची सामान्य पातळी गाठेपर्यंत कदाचित बॅटरी संपू शकते"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"बॅटरी लाइफ वाढवण्यासाठी बॅटरी सेव्हर सुरू केला आहे"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"बॅटरी सेव्‍हर"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"बॅटरी पुन्हा कमी होईपर्यंत बॅटरी सेव्हर पुन्हा अ‍ॅक्टिव्हेट होणार नाही"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"बॅटरी पुरेशा पातळीवर चार्ज झालेली आहे. बॅटरी पुन्हा कमी होईपर्यंत बॅटरी सेव्हर पुन्हा अ‍ॅक्टिव्हेट होणार नाही."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"फोन <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज झाला"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"टॅबलेट <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज झाले"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"डिव्हाइस <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज झाले"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"बॅटरी सेव्हर बंद आहे. वैशिष्ट्ये मर्यादित नाहीत."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"बॅटरी सेव्हर बंद केलेला आहे. वैशिष्ट्ये मर्यादित नाहीत."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"फोल्डर"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android अ‍ॅप्लिकेशन"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"फाइल"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1386e7a..a29e363 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"menghantar dan melihat mesej SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Storan"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"mengakses foto, media dan fail pada peranti anda"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"rakam audio"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Boleh ketik, leret, cubit dan laksanakan gerak isyarat lain."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gerak isyarat cap jari"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Boleh menangkap gerak isyarat yang dilakukan pada penderia cap jari peranti."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"lumpuhkan atau ubah suai bar status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"jadi bar status"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Naikkan kelantangan melebihi paras yang disyokorkan?\n\nMendengar pada kelantangan yang tinggi untuk tempoh yang lama boleh merosakkan pendengaran anda."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Kebolehaksesan?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Apabila pintasan dihidupkan, tindakan menekan kedua-dua butang kelantangan selama 3 saat akan memulakan ciri kebolehaksesan.\n\n Ciri kebolehaksesan semasa:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Anda boleh menukar ciri itu dalam Tetapan &gt; Kebolehaksesan."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Kosong"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit pintasan"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Batal"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Matikan pintasan"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Hidupkan profil kerja?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Apl kerja, pemberitahuan, data dan ciri profil kerja anda yang lain akan dihidupkan"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Hidupkan"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Apl ini dibina untuk versi Android yang lebih lama dan mungkin tidak berfungsi dengan betul. Cuba semak kemas kini atau hubungi pembangun."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Semak kemas kini"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Anda mempunyai mesej baharu"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateri mungkin habis sebelum pengecasan biasa"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Penjimat Bateri diaktifkan untuk memanjangkan hayat bateri"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Penjimat Bateri"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Penjmat Bateri tidak akan diaktifkan semula sehingga bateri rendah sekali lagi"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Bateri sudah dicas pada aras yang mencukupi Penjimat Bateri tidak akan diaktifkan semula sehingga bateri rendah sekali lagi."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon dicas <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet dicas <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Peranti dicas <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Penjimat Bateri dimatikan. Ciri tidak lagi dihadkan."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Penjimat Bateri dimatikan. Ciri tidak lagi dihadkan."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikasi Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fail"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index ff08a59..a53deaf 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS စာတိုစနစ်"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"သိုလှောင်မှုများ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"သင့်ဖုန်းရှိ ဓာတ်ပုံများ၊ မီဒီယာနှင့် ဖိုင်များအား ဝင်သုံးပါ"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"မိုက်ခရိုဖုန်း"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"အသံဖမ်းခြင်း"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"တို့ခြင်း၊ ပွတ်ဆွဲခြင်း၊ နှင့် အခြား လက်ဟန်များကို အသုံးပြုနိုင်ပါသည်။"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"လက်ဗွေဟန်များ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"စက်ပစ္စည်း၏ လက်ဗွေအာရုံခံကိရိယာတွင် လုပ်ဆောင်ထားသည့် လက်ဟန်များကို မှတ်သားထားနိုင်သည်။"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"အခြေအနေပြဘားအား အလုပ်မလုပ်ခိုင်းရန်သို့မဟုတ် မွမ်းမံရန်"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"အက်ပ်အား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"အခြေအနေပြ ဘားဖြစ်ပါစေ"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"အသံကို အကြံပြုထားသည့် ပမာဏထက် မြှင့်ပေးရမလား?\n\nအသံကို မြင့်သည့် အဆင့်မှာ ကြာရှည်စွာ နားထောင်ခြင်းက သင်၏ နားကို ထိခိုက်စေနိုင်သည်။"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်ကို အသုံးပြုလိုပါသလား။"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ဖြတ်လမ်းလင့်ခ်ကို ဖွင့်ထားစဉ် အသံအတိုးအလျှော့ခလုတ် နှစ်ခုစလုံးကို ၃ စက္ကန့်ခန့် ဖိထားခြင်းဖြင့် အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှုကို ဖွင့်နိုင်သည်။\n\n လက်ရှိ အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှု−\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ဝန်ဆောင်မှုကို ဆက်တင်များ &gt; အများသုံးစွဲနိုင်မှုတွင် ပြောင်းလဲနိုင်ပါသည်။"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"အလွတ်"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ဖြတ်လမ်းများကို တည်းဖြတ်ရန်"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"မလုပ်တော့"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ဖြတ်လမ်းလင့်ခ်ကို ပိတ်ရန်"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ဖြတ်လမ်းလင့်ခ်ကို သုံးရန်"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"အရောင် ပြောင်းပြန်လှန်ခြင်း"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"အလုပ်ပရိုဖိုင် ဖွင့်လိုသလား။"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"သင်၏ အလုပ်အက်ပ်၊ အကြောင်းကြားချက်၊ ဒေတာနှင့် အခြားအလုပ်ပရိုဖိုင် ဝန်ဆောင်မှုများကို ဖွင့်လိုက်ပါမည်"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ဖွင့်ပါ"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ဤအက်ပ်ကို Android ဗားရှင်းဟောင်းအတွက် ပြုလုပ်ထားခြင်းဖြစ်ပြီး ပုံမှန်အလုပ်မလုပ်နိုင်ပါ။ အပ်ဒိတ်များအတွက် ရှာကြည့်ပါ သို့မဟုတ် ဆော့ဖ်ဝဲအင်ဂျင်နီယာကို ဆက်သွယ်ပါ။"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"အပ်ဒိတ်စစ်ရန်"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"သင့်ထံတွင် စာအသစ်များရောက်နေသည်"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ပုံမှန်အားသွင်းမှုမပြုလုပ်မီ ဘက်ထရီကုန်သွားနိုင်သည်"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ဘက်ထရီသက်တမ်းကို တိုးမြှင့်ရန် \'ဘက်ထရီအားထိန်း\' စတင်ပြီးပါပြီ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ဘက်ထရီ အားထိန်း"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"နောက်တစ်ကြိမ် ဘက်ထရီအားနည်းသွားသည်အထိ \'ဘက်ထရီအားထိန်း\' ပြန်ပွင့်မည် မဟုတ်ပါ"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ဘက်ထရီကို လုံလောက်သည့်ပမာဏသို့ အားသွင်းထားပါသည်။ နောက်တစ်ကြိမ် ဘက်ထရီအားနည်းသွားသည်အထိ \'ဘက်ထရီအားထိန်း\' ပြန်ပွင့်မည် မဟုတ်ပါ။"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ဖုန်း <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> အားသွင်းထားသည်"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"တက်ဘလက် <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> အားသွင်းထားသည်"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"စက်ပစ္စည်း <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> အားသွင်းထားသည်"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"\'ဘက်ထရီအားထိန်း\' ကိုပိတ်ထားသည်။ ဝန်ဆောင်မှုများကို ကန့်သတ်မထားတော့ပါ။"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"\'ဘက်ထရီ အားထိန်း\' ပိတ်ထားသည်။ ဝန်ဆောင်မှုများကို ကန့်သတ်မထားတော့ပါ။"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ဖိုင်တွဲ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android အပလီကေးရှင်း"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ဖိုင်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3e23679..ee16f90 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"åpne kalenderen din"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og lese SMS-meldinger"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Lagring"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"åpne bilder, medieinnhold og filer på enheten din"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ta opp lyd"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan trykke, sveipe, klype og gjøre andre bevegelser."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Bevegelser på fingeravtrykkssensor"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan fange inn bevegelser som utføres på enhetens fingeravtrykkssensor."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller endre statusfeltet"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Lar appen deaktivere statusfeltet eller legge til og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vise appen i statusfeltet"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du øke volumet til over anbefalt nivå?\n\nHvis du hører på et høyt volum over lengre perioder, kan det skade hørselen din."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruke tilgjengelighetssnarveien?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Når snarveien er på, starter en tilgjengelighetsfunksjon når du trykker inn begge volumknappene i tre sekunder.\n\n Nåværende tilgjengelighetsfunksjon:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kan endre funksjonen i Innstillinger &gt; Tilgjengelighet."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Tøm"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Endre snarveier"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Avbryt"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Slå av snarveien"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Vil du slå på jobbprofilen?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Jobbappene dine samt varsler, data og andre funksjoner i jobbprofilen din blir slått på"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Slå på"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Denne appen er utviklet for en eldre versjon av Android og fungerer kanskje ikke som den skal. Prøv å se etter oppdateringer, eller kontakt utvikleren."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Se etter oppdateringer"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye meldinger"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batteriet kan gå tomt før den vanlige ladingen"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparing er aktivert for å forlenge batterilevetiden"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparing"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Batterisparing blir ikke aktivert igjen før batteriet er lavt"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batteriet er blitt ladet til et tilstrekkelig nivå. Batterisparing blir ikke aktivert igjen før batteriet er lavt."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefonen er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ladet"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Nettbrettet er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ladet"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Enheten er <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ladet"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Batterisparing er av. Funksjoner begrenses ikke lenger."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Batterisparing er slått av. Funksjoner begrenses ikke lenger."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Mappe"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-app"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fil"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index d7e121c..1b85b28 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"तपाईंको पात्रोमाथि पहुँच गर्नुहोस्"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"भण्डारण"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"तपाईंको यन्त्रमा तस्बिर, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"अडियो रेकर्ड गर्नुहोस्"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ट्याप, स्वाइप गर्न, थिच्न र अन्य इसाराहरू सम्बन्धी कार्य गर्न सक्छ"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"फिंगरप्रिन्टका इसाराहरू"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"यसले यन्त्रक‍ो फिंगरप्रिन्टसम्बन्धी सेन्सरमा गरिएका इसाराहरूलाई खिच्‍न सक्छ।"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"वस्तुस्थिति पट्टी हुन दिनुहोस्"</string>
@@ -1616,6 +1621,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"सर्टकट सक्रिय हुँदा, भोल्युमका दुवै बटनहरूलाई ३ सेकेन्डसम्म थिची राख्नाले पहुँच सम्बन्धी कुनै सुविधा सुरु हुनेछ।\n\n हाल व्यवहारमा रहेको पहुँच सम्बन्धी सुविधा:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n तपाईं सेटिङहरू अन्तर्गतको पहुँच सम्बन्धी विकल्पमा गई उक्त सुविधालाई बदल्न सक्नुहुन्छ।"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"खाली"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"सर्टकटहरू सम्पादन गर्नुहोस्"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"रद्द गर्नुहोस्"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"सर्टकटलाई निष्क्रिय पार्नुहोस्"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"रङ्ग उल्टाउने सुविधा"</string>
@@ -1851,6 +1859,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"कार्य प्रोफाइल सक्रिय गर्ने?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"तपाईंका कार्यसम्बन्धी अनुप्रयोग, सूचना, डेटा र कार्य प्रोफाइलका अन्य सुविधाहरू सक्रिय गरिने छन्‌"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"सक्रिय गर्नुहोस्"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"यो अनुप्रयोग Android को पुरानो संस्करणका लागि बनाइएको हुनाले यसले सही ढङ्गले काम नगर्न सक्छ। अद्यावधिकहरू उपलब्ध छन् वा छैनन् भनी जाँच गरी हेर्नुहोस् वा यसको विकासकर्तालाई सम्पर्क गर्नुहोस्।"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अद्यावधिक उपलब्ध छ वा छैन भनी जाँच गर्नुहोस्"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"तपाईंलाई नयाँ सन्देश आएको छ"</string>
@@ -1961,13 +1973,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"प्रायः चार्ज गर्ने समय हुनुभन्दा पहिले नै ब्याट्री सकिन सक्छ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ब्याट्रीको आयु बढाउन ब्याट्री सेभर सक्रिय गरियो"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ब्याट्री सेभर"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"फेरि ब्याट्री कम नभएसम्म ब्याट्री सेभर पुनः सक्रिय हुने छैन"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ब्याट्री पर्याप्त हुने गरी चार्ज गरिएको छ। ब्याट्रीको चार्ज कम नभएसम्म ब्याट्री सेभर पुनः सक्रिय हुने छैन।"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"फोन <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज भयो"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ट्याब्लेट <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज भयो"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"यन्त्र <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> चार्ज गरियो"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ब्याट्री सेभर निष्क्रिय छ। सुविधाहरूलाई अब उप्रान्त प्रतिबन्ध लगाइँदैन।"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ब्याट्री सेभर निष्क्रिय पारियो। सुविधाहरूलाई अब उप्रान्त प्रतिबन्ध लगाइँदैन।"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"फोल्डर"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android अनुप्रयोग"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"फाइल"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b342941..dece9ae 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"toegang krijgen tot je agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sms\'jes verzenden en bekijken"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Opslagruimte"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Bestanden en media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"toegang krijgen tot foto\'s, media en bestanden op je apparaat"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfoon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"audio opnemen"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan tikken, vegen, samenknijpen en andere gebaren uitvoeren."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Vingerafdrukgebaren"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan gebaren registreren die op de vingerafdruksensor van het apparaat worden getekend."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot maken"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan een screenshot van het scherm maken."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"statusbalk uitschakelen of wijzigen"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Hiermee kan de app de statusbalk uitschakelen of systeempictogrammen toevoegen en verwijderen."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"de statusbalk zijn"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls je langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Snelkoppeling toegankelijkheid gebruiken?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Wanneer de snelkoppeling is ingeschakeld, kun je drie seconden op beide volumeknoppen drukken om een toegankelijkheidsfunctie te starten.\n\n Huidige toegankelijkheidsfunctie:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Je kunt de functie wijzigen in Instellingen &gt; Toegankelijkheid."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Leeg"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Snelkoppelingen bewerken"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuleren"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Sneltoets uitschakelen"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Werkprofiel inschakelen?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Je werk-apps, meldingen, gegevens en andere functies van je werkprofiel worden uitgeschakeld"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Inschakelen"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Deze app is ontwikkeld voor een oudere versie van Android en werkt mogelijk niet op de juiste manier. Controleer op updates of neem contact op met de ontwikkelaar."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Controleren op update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Je hebt nieuwe berichten"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"De batterij raakt mogelijk leeg voordat deze normaal gesproken wordt opgeladen"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterijbesparing is geactiveerd om de batterijduur te verlengen"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterijbesparing"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Batterijbesparing kan pas opnieuw worden geactiveerd zodra de batterij bijna leeg is"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batterij is voldoende opgeladen. Batterijbesparing kan pas opnieuw worden geactiveerd zodra de batterij bijna leeg is."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefoon is <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> opgeladen"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet is <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> opgeladen"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Apparaat is <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> opgeladen"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Batterijbesparing staat uit. Functies worden niet meer beperkt."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Batterijbesparing is uitgeschakeld. Functies worden niet meer beperkt."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Batterijbesparing is uitgeschakeld"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefoon is voldoende opgeladen. Functies worden niet meer beperkt."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Tablet is voldoende opgeladen. Functies worden niet meer beperkt."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Apparaat is voldoende opgeladen. Functies worden niet meer beperkt."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Map"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-app"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Bestand"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index b12c655..2018a7f 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍‍ ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ମେସେଜ୍‍ ପଠାନ୍ତୁ ଓ ଦେଖନ୍ତୁ"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ଷ୍ଟୋରେଜ୍‌"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ଥିବା ଫଟୋ, ମିଡିଆ ଓ ଫାଇଲ୍‍ ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ମାଇକ୍ରୋଫୋନ୍"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ଅଡିଓ ରେକର୍ଡ କରେ"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ଟାପ୍‍, ସ୍ୱାଇପ୍‍, ପିଞ୍ଚ ଓ ଅନ୍ୟାନ୍ୟ ଜେଶ୍ଚର୍‍ ସମ୍ପାଦନ କରିପାରିବ।"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ଟିପଚିହ୍ନ ଜେଶ୍ଚର"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ଡିଭାଇସ୍‌ର ଟିପଚିହ୍ନ ସେନସର୍ ଉପରେ ଜେଶ୍ଚର୍‍ କ୍ୟାପଚର୍‍ କାର୍ଯ୍ୟ କରାଯାଇପାରିବ।"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"ଷ୍ଟାଟସ୍‌ ବାର୍‌କୁ ଅକ୍ଷମ କିମ୍ୱା ସଂଶୋଧନ କରନ୍ତୁ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ଆପ୍‍କୁ, ସ୍ଥିତି ବାର୍‍ ଅକ୍ଷମ କରିବାକୁ କିମ୍ବା ସିଷ୍ଟମ୍‍ ଆଇକନ୍‍ ଯୋଡ଼ିବା କିମ୍ବା ବାହାର କରିବାକୁ ଦେଇଥାଏ।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ଷ୍ଟାଟସ୍‍ ବାର୍‍ ରହିବାକୁ ଦିଅନ୍ତୁ"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ମାତ୍ରା ବଢ଼ାଇ ସୁପାରିଶ ସ୍ତର ବଢ଼ାଉଛନ୍ତି? \n\n ଲମ୍ବା ସମୟ ପର୍ଯ୍ୟନ୍ତ ଉଚ୍ଚ ଶବ୍ଦରେ ଶୁଣିଲେ ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତି ଖରାପ ହୋଇପାରେ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ଆକ୍ସେସବିଲିଟି ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରିବେ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ସର୍ଟକଟ୍‌ ଅନ୍‌ ଥିବା ବେଳେ, ଉଭୟ ଭଲ୍ୟୁମ୍‍ ବଟନ୍‍ 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇବା ଦ୍ୱାରା ଆକ୍ସେସବିଲିଟି ବୈଶିଷ୍ଟ ଆରମ୍ଭ ହେବ।\n\n ସମ୍ପ୍ରତି ଆକ୍ସେସବିଲିଟି ବୈଶିଷ୍ଟ୍ୟ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ସେଟିଙ୍ଗ ଓ ଆକ୍ସେସବିଲିଟିରେ ଆପଣ ବୈଶିଷ୍ଟ୍ୟ ବଦଳାଇ ପାରିବେ।"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ଖାଲି କରନ୍ତୁ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ଶର୍ଟକଟ୍‍ ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ରଙ୍ଗ ବଦଳାଇବାର ସୁବିଧା"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ଚାଲୁ କରିବେ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"ଆପଣଙ୍କର କାର୍ଯ୍ୟକାରୀ ଆପ୍‌, ବିଜ୍ଞପ୍ତି, ଡାଟା ଓ ଅନ୍ୟ ୱର୍କ ପ୍ରୋଫାଇଲ୍‌ଗୁଡ଼ିକ ଚାଲୁ ହୋଇଯିବ"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ଅନ୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ଏହି ଆପ୍‌କୁ Androidର ପୁରୁଣା ଭର୍ସନ୍ ପାଇଁ ନିର୍ମାଣ କରାଯାଇଥିଲା ଏବଂ ଠିକ୍ ଭାବେ କାମ କରିନପାରେ। ଏହାପାଇଁ ଅପଡେଟ୍‌ ଅଛି କି ନାହିଁ ଯାଞ୍ଚ କରନ୍ତୁ କିମ୍ବା ଡେଭେଲପର୍‌ଙ୍କ ସହିତ ସମ୍ପର୍କ କରନ୍ତୁ।"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ଅପଡେଟ୍‌ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"ଆପଣଙ୍କ ପାଖରେ ନୂଆ ମେସେଜ୍‍ ରହିଛି"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ସାଧାରଣ ଭାବରେ ଚାର୍ଜ୍ କରିବା ପୂର୍ବରୁ ବ୍ୟାଟେରୀ ସରିଯାଇପାରେ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ବ୍ୟାଟେରୀର ସମୟକୁ ବଢ଼ାଇବା ପାଇଁ ବ୍ୟଟେରୀ ସେଭର୍‍କୁ କାର୍ଯ୍ୟକାରୀ କରାଯାଇଛି"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ବ୍ୟାଟେରୀ ସେଭର୍"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ବ୍ୟାଟେରୀ ଟାର୍ଜ କମ୍ ନହେବା ପର୍ଯ୍ୟନ୍ତ ବ୍ୟାଟେରୀ ସେଭର୍‌ ପୁନଃସକ୍ରିୟ ହୁଏ ନାହିଁ"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ବ୍ୟାଟେରୀ ଏକ ପର୍ଯ୍ୟାପ୍ତ ସ୍ତର ପର୍ଯ୍ୟନ୍ତ ଚାର୍ଜ ହୋଇଛି। ବ୍ୟାଟେରୀ ପୁଣି କମ୍ ନହେବା ପର୍ଯ୍ୟନ୍ତ ବ୍ୟାଟେରୀ ସେଭର୍‌ ପୁନଃସକ୍ରିୟ ହେବନାହିଁ।"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ଫୋନ୍ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ଚାର୍ଜ ହୋଇଛି"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ଟାବ୍‌ଲେଟ୍‌ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ଚାର୍ଜ ହୋଇଛି"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ଡିଭାଇସ୍ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ଚାର୍ଜ ହୋଇଛି"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ବ୍ୟାଟେରୀ ସେଭର୍ ବନ୍ଦ ଅଛି ବୈଶିଷ୍ଟ୍ୟ ଆଉ ପ୍ରତିବନ୍ଧିତ ନୁହେଁ।"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ବନ୍ଦ ଅଛି। ବୈଶିଷ୍ଟ୍ୟ ଆଉ ପ୍ରତିବନ୍ଧିତ ନୁହେଁ।"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ଫୋଲ୍ଡର୍"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ଆପ୍ଲିକେସନ୍"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ଫାଇଲ୍"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 72e695e..552f77d 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦੇਖੋ"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ਸਟੋਰੇਜ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨਾ"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">" ਆਡੀਓ  ਰਿਕਾਰਡ ਕਰਨ"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"ਟੈਪ ਕਰ ਸਕਦੀ ਹੈ, ਸਵਾਈਪ ਕਰ ਸਕਦੀ ਹੈ, ਚੂੰਢੀ ਭਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਹੋਰ ਸੰਕੇਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੰਕੇਤ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ਡੀਵਾਈਸਾਂ ਦੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ \'ਤੇ ਕੀਤੇ ਗਏ ਸੰਕੇਤਾਂ ਨੂੰ ਕੈਪਚਰ ਕਰ ਸਕਦੇ ਹਨ।"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"ਸਥਿਤੀ ਪੱਟੀ ਬੰਦ ਕਰੋ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਨੂੰ ਚਾਲੂ ਕਰਨ ਜਾਂ ਸਿਸਟਮ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ਸਥਿਤੀ ਪੱਟੀ ਬਣਨ ਦਿਓ"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ਕੀ ਵੌਲਿਊਮ  ਸਿਫ਼ਾਰਸ਼  ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਵਰਤਣਾ ਹੈ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਅਵਾਜ਼ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।\n\n ਵਰਤਮਾਨ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ਤੁਸੀਂ ਸੈਟਿੰਗਾਂ &gt; ਪਹੁੰਚਯੋਗਤਾ ਵਿੱਚ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ਖਾਲੀ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ਸ਼ਾਰਟਕੱਟਾਂ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ਰੱਦ ਕਰੋ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ਸ਼ਾਰਟਕੱਟ ਬੰਦ ਕਰੋ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"ਰੰਗ ਦੀ ਉਲਟੀ ਤਰਤੀਬ"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"ਕੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਚਾਲੂ ਕਰਨੀ ਹੈ?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"ਤੁਹਾਡੀਆਂ ਕਾਰਜ-ਸਥਾਨ ਐਪਾਂ, ਸੂਚਨਾਵਾਂ, ਡਾਟਾ ਅਤੇ ਹੋਰ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਚਾਲੂ ਕੀਤੀਆਂ ਜਾਣਗੀਆਂ"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ਚਾਲੂ ਕਰੋ"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਵਧੇਰੇ ਪੁਰਾਣੇ ਵਰਜਨ ਲਈ ਬਣਾਈ ਗਈ ਸੀ ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ। ਅੱਪਡੇਟਾਂ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ਅੱਪਡੇਟ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ਬੈਟਰੀ ਚਾਰਜ ਕਰਨ ਦੇ ਮਿੱਥੇ ਸਮੇਂ ਤੋਂ ਪਹਿਲਾਂ ਸ਼ਾਇਦ ਬੈਟਰੀ ਖਤਮ ਹੋ ਜਾਵੇ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ਬੈਟਰੀ ਸੇਵਰ"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"ਬੈਟਰੀ ਸੇਵਰ ਦੁਬਾਰਾ ਬੈਟਰੀ ਘਟਣ ਤੱਕ ਮੁੜ-ਕਿਰਿਆਸ਼ੀਲ ਨਹੀਂ ਹੁੰਦਾ ਹੈ"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ਬੈਟਰੀ ਲੋੜੀਂਦੇ ਪੱਧਰ ਤੱਕ ਚਾਰਜ ਹੋ ਗਈ ਹੈ। ਬੈਟਰੀ ਸੇਵਰ ਦੁਬਾਰਾ ਬੈਟਰੀ ਘਟਣ ਤੱਕ ਮੁੜ-ਕਿਰਿਆਸ਼ੀਲ ਨਹੀਂ ਹੁੰਦਾ।"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ਫ਼ੋਨ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ਚਾਰਜ ਹੋਇਆ"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ਟੈਬਲੈੱਟ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ਚਾਰਜ ਹੋਇਆ"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"ਡੀਵਾਈਸ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ਚਾਰਜ ਹੋਇਆ"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"ਬੈਟਰੀ ਸੇਵਰ ਬੰਦ ਹੈ। ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਹੁਣ ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ ਹਨ।"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ਬੈਟਰੀ ਸੇਵਰ ਬੰਦ ਕੀਤਾ ਗਿਆ। ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਹੁਣ ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ ਹਨ।"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ਫੋਲਡਰ"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ਐਪਲੀਕੇਸ਼ਨ"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ਫ਼ਾਈਲ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4f6e748..5f94b18 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostęp do kalendarza"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"wysyłanie i wyświetlanie SMS‑ów"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Pamięć"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"dostęp do zdjęć, multimediów i plików na Twoim urządzeniu"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nagrywanie dźwięku"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Obsługuje kliknięcia, przesunięcia, ściągnięcia palców i inne gesty."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gesty związane z odciskiem palca"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Może przechwytywać gesty wykonywane na czytniku linii papilarnych w urządzeniu."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"wyłączanie lub zmienianie paska stanu"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"działanie jako pasek stanu"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zwiększyć głośność ponad zalecany poziom?\n\nSłuchanie głośno przez długi czas może uszkodzić Twój słuch."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Użyć skrótu do ułatwień dostępu?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Gdy skrót jest włączony, jednoczesne naciśnięcie przez trzy sekundy obu klawiszy sterowania głośnością uruchomi funkcję ułatwień dostępu.\n\nBieżąca funkcja ułatwień dostępu:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nFunkcję możesz zmienić, wybierając Ustawienia &gt; Ułatwienia dostępu."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Puste"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edytuj skróty"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Anuluj"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Wyłącz skrót"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Włączyć profil służbowy?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacje do pracy, powiadomienia, dane i inne funkcje profilu do pracy zostaną włączone"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Włącz"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ta aplikacja jest na starszą wersję Androida i może nie działać prawidłowo. Sprawdź dostępność aktualizacji lub skontaktuj się z programistą."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sprawdź dostępność aktualizacji"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Masz nowe wiadomości"</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria może się wyczerpać przed zwykłą porą ładowania"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Włączono Oszczędzanie baterii, by wydłużyć czas pracy na baterii"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Oszczędzanie baterii"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Oszczędzanie baterii nie włączy się ponownie do czasu rozładowania baterii"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Poziom naładowania baterii jest wystarczający. Oszczędzanie baterii nie włączy się ponownie do czasu rozładowania baterii."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Poziom naładowania telefonu: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Poziom naładowania tabletu: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Poziom naładowania urządzenia: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Oszczędzanie baterii jest wyłączone. Funkcje nie są już ograniczone."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Oszczędzanie baterii zostało wyłączone. Funkcje nie są już ograniczone."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikacja na Androida"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Plik"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f4c9e34..567d6d4 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Armazenamento"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Arquivos e mídia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"acesse fotos, mídia e arquivos do dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grave áudio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Toque, deslize, faça gestos de pinça e faça outros gestos."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos de impressão digital"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer uma captura de tela"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode fazer uma captura de tela."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser a barra de status"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando o atalho está ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade.\n\n Recurso de acessibilidade atual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n É possível alterar o recurso em Configurações &gt; Acessibilidade."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Limpar"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ativar o perfil de trabalho?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Seus apps, notificações, dados e outros recursos do perfil de trabalho serão ativados"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Este app foi criado para uma versão mais antiga do Android e pode não funcionar corretamente. Tente verificar se há atualizações ou entre em contato com o desenvolvedor."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A bateria pode acabar antes da recarga normal"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"A Economia de bateria foi ativada para aumentar a duração da carga"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Economia de bateria"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"A Economia de bateria só será reativada quando a bateria estiver acabando novamente"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"A bateria foi carregada até o nível suficiente. A Economia de bateria só será reativada quando a bateria estiver acabando novamente."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Smartphone <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> carregado"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> carregado"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Dispositivo <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> carregado"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Economia de bateria desativada. Os recursos não estão mais restritos."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Economia de bateria desativada. Os recursos não estão mais restritos."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"\"Economia de bateria\" desativada"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Não há carga suficiente no smartphone. Os recursos não estão mais restritos."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Não há carga suficiente no tablet. Os recursos não estão mais restritos."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Não há carga suficiente no dispositivo. Os recursos não estão mais restritos."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Pasta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicativo Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Arquivo"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 65913ce..b746c92 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"aceder ao calendário"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e ver mensagens SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Armazenamento"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Ficheiros e multimédia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"aceder a fotos, multimédia e ficheiros no dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar áudio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"É possível tocar, deslizar rapidamente, juntar os dedos e realizar outros gestos"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos de impressão digital"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode capturar gestos realizados no sensor de impressões digitais do dispositivo."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tirar captura de ecrã"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"É possível tirar uma captura de ecrã."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite à aplicação desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser apresentada na barra de estado"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir com um volume elevado durante longos períodos poderá ser prejudicial para a sua audição."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Pretende utilizar o atalho de acessibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando o atalho está ativado, premir ambos os botões de volume durante 3 segundos inicia uma funcionalidade de acessibilidade.\n\n Funcionalidade de acessibilidade atual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Pode alterar a funcionalidade em Definições &gt; Acessibilidade."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Esvaziar"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atalho"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
@@ -1731,7 +1736,7 @@
     <string name="restr_pin_try_later" msgid="5897719962541636727">"Tente novamente mais tarde"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização de ecrã inteiro"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize rapidamente para baixo a partir da parte superior."</string>
-    <string name="immersive_cling_positive" msgid="7047498036346489883">"Compreendi"</string>
+    <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
     <string name="done_label" msgid="7283767013231718521">"Concluído"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Controlo de deslize circular das horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Controlo de deslize circular dos minutos"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ativar o perfil de trabalho?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"As aplicações de trabalho, as notificações, os dados e outras funcionalidades do perfil de trabalho serão desativados"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta aplicação foi concebida para uma versão mais antiga do Android e pode não funcionar corretamente. Experimente verificar se existem atualizações ou contacte o programador."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verificar se existem atualizações"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Tem mensagens novas"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pode ficar sem bateria antes do carregamento habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Poupança de bateria ativada para prolongar a duração da bateria"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Poupança de bateria"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"A Poupança de bateria não será reativada até a bateria estar novamente fraca"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"A bateria foi carregada até um nível suficiente. A Poupança de bateria não será reativada até a bateria estar novamente fraca."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"O telemóvel tem um nível de carga de <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"O tablet tem um nível de carga de <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"O dispositivo tem um nível de carga de <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"A Poupança de bateria está desativada. As funcionalidades já não estão restritas."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"A Poupança de bateria está desativada. As funcionalidades já não estão restritas."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"A Poupança de bateria está desativada"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"O telemóvel tem carga suficiente. As funcionalidades já não estão restritas."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"O tablet tem carga suficiente. As funcionalidades já não estão restritas."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"O dispositivo tem carga suficiente. As funcionalidades já não estão restritas."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Pasta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicação para Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Ficheiro"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f4c9e34..567d6d4 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Armazenamento"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Arquivos e mídia"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"acesse fotos, mídia e arquivos do dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"grave áudio"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Toque, deslize, faça gestos de pinça e faça outros gestos."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos de impressão digital"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer uma captura de tela"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode fazer uma captura de tela."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser a barra de status"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando o atalho está ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade.\n\n Recurso de acessibilidade atual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n É possível alterar o recurso em Configurações &gt; Acessibilidade."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Limpar"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ativar o perfil de trabalho?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Seus apps, notificações, dados e outros recursos do perfil de trabalho serão ativados"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Este app foi criado para uma versão mais antiga do Android e pode não funcionar corretamente. Tente verificar se há atualizações ou entre em contato com o desenvolvedor."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A bateria pode acabar antes da recarga normal"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"A Economia de bateria foi ativada para aumentar a duração da carga"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Economia de bateria"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"A Economia de bateria só será reativada quando a bateria estiver acabando novamente"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"A bateria foi carregada até o nível suficiente. A Economia de bateria só será reativada quando a bateria estiver acabando novamente."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Smartphone <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> carregado"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> carregado"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Dispositivo <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> carregado"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Economia de bateria desativada. Os recursos não estão mais restritos."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Economia de bateria desativada. Os recursos não estão mais restritos."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"\"Economia de bateria\" desativada"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Não há carga suficiente no smartphone. Os recursos não estão mais restritos."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Não há carga suficiente no tablet. Os recursos não estão mais restritos."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Não há carga suficiente no dispositivo. Os recursos não estão mais restritos."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Pasta"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicativo Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Arquivo"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5b50ef7..5b115375 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -290,7 +290,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceseze calendarul"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"trimită și să vadă mesajele SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Stocare"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"acceseze fotografiile, conținutul media și fișierele de pe dispozitiv"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"înregistreze sunet"</string>
@@ -316,6 +317,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Poate atinge, glisa, ciupi sau folosi alte gesturi."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gesturi ce implică amprente"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Poate reda gesturile făcute pe senzorul de amprentă al dispozitivului."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"dezactivare sau modificare bare de stare"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite aplicației să dezactiveze bara de stare sau să adauge și să elimine pictograme de sistem."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"să fie bara de stare"</string>
@@ -1632,6 +1637,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ridicați volumul mai sus de nivelul recomandat?\n\nAscultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utilizați comanda rapidă pentru accesibilitate?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Când comanda rapidă este activată, dacă apăsați ambele butoane de volum timp de 3 secunde, veți lansa o funcție de accesibilitate.\n\n Funcția actuală de accesibilitate:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puteți schimba funcția în Setări &gt; Accesibilitate."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Goliți"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editați comenzile rapide"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Anulați"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Dezactivați comanda rapidă"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizați comanda rapidă"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversarea culorilor"</string>
@@ -1877,6 +1885,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Activați profilul de serviciu?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Se vor activa aplicațiile dvs. de serviciu, notificările, datele și alte funcții ale profilului de serviciu"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activați"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Această aplicație a fost creată pentru o versiune Android mai veche și este posibil să nu funcționeze corect. Încercați să căutați actualizări sau contactați dezvoltatorul."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Căutați actualizări"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Aveți mesaje noi"</string>
@@ -1988,13 +2000,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria se poate descărca înainte de încărcarea obișnuită"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Economisirea bateriei este activată pentru a prelungi durata de funcționare a bateriei"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Economisirea bateriei"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Economisirea bateriei se va reactiva când bateria va fi descărcată din nou"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Bateria s-a încărcat la un nivel suficient. Economisirea bateriei se va reactiva când bateria va fi descărcată din nou."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefonul este încărcat <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tableta este încărcată <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Dispozitivul este încărcat <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Economisirea bateriei este dezactivată. Funcțiile nu mai sunt limitate."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Economisirea bateriei a fost dezactivată. Funcțiile nu mai sunt limitate."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Dosar"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplicație Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fișier"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 9e8e13a..fa283d8 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"доступ к календарю"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"отправлять и просматривать SMS-сообщения"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Хранилище"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"доступ к фото, мультимедиа и файлам на вашем устройстве"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"записывать аудио"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Может выполнять жесты нажатия, пролистывания, масштабирования и т. д."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Регистрировать жесты на сканере отпечатков пальцев"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Использовать сканер отпечатков пальцев для дополнительных жестов."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"Отключение/изменение строки состояния"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Замена строки состояния"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Установить громкость выше рекомендуемого уровня?\n\nВоздействие громкого звука в течение долгого времени может привести к повреждению слуха."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Использовать быстрое включение?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Чтобы использовать функцию специальных возможностей, когда она включена, нажмите и удерживайте три секунды обе кнопки регулировки громкости.\n\nТекущая функция специальных возможностей:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nВы можете изменить ее в разделе \"Настройки &gt; Специальные возможности\"."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Очистить"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Изменить быстрые клавиши"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Отмена"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Деактивировать быстрое включение"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Использовать быстрое включение"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверсия цветов"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Включить рабочий профиль?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Будут включены корпоративные приложения, уведомления, данные и другие функции рабочего профиля."</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Включить"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Это приложение было создано для более ранней версии Android и может работать со сбоями. Проверьте наличие обновлений или свяжитесь с разработчиком."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверить обновления"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Новые сообщения"</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея может разрядиться"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Чтобы увеличить время работы от батареи, был включен режим энергосбережения."</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим энергосбережения"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Режим энергосбережения будет включен снова при низком уровне заряда батареи."</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батарея заряжена достаточно. Режим энергосбережения будет включен снова при низком уровне заряда батареи."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефон заряжен на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Планшет заряжен на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Устройство заряжено на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Режим энергосбережения выключен. Функции больше не ограничены."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Режим энергосбережения выключен. Функции больше не ограничены."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Приложение Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index a28e036..3899cd7 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"කෙටි පණිවිඩ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS පණිවිඩ යැවීම සහ බැලීම"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"ආචයනය"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ඔබේ උපාංගයේ ඇති ඡායාරූප, මාධ්‍ය සහ ගොනුවලට පිවිසීම"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"මයික්‍රොෆෝනය"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ශ්‍රව්‍ය පටිගත කරන්න"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"තට්ටු කිරීමට, ස්වයිප් කිරීමට, පින්ච් කිරීමට, සහ වෙනත් අභින සිදු කිරීමට හැකිය."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ඇඟිලි සලකුණු ඉංගිත"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"උපාංගයෙහි ඇඟිලි සලකුණු සංවේදකය මත සිදු කරන ඉංගිත ග්‍රහණය කළ හැකිය."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"තත්ව තීරුව අක්‍රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"තත්ත්ව තීරුව බවට පත්වීම"</string>
@@ -1612,6 +1617,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"නිර්දේශිතයි මට්ටමට වඩා ශබ්දය වැඩිද?\n\nදිගු කාලයක් සඳහා ඉහළ ශබ්දයක් ඇසීමෙන් ඇතැම් විට ඔබගේ ඇසීමට හානි විය හැක."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ප්‍රවේශ්‍යතා කෙටිමඟ භාවිතා කරන්නද?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"කෙටිමඟ සක්‍රිය විට, හඬ බොත්තම් දෙකම තත්පර 3ක් අල්ලාගෙන සිටීමෙන් ප්‍රවේශ්‍යත අංගයක් ඇරඹේ.\n\n වත්මන් ප්‍රවේශ්‍යතා අංගය:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n සැකසීම් &gt; ප්‍රවේශ්‍යතාව තුළ ඔබට අංගය වෙනස් කළ හැක."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"හිස්"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"කෙටිමං සංස්කරණ කරන්න"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"අවලංගු කරන්න"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"කෙටිමඟ ක්‍රියාවිරහිත කරන්න"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"කෙටිමඟ භාවිතා කරන්න"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"වර්ණ අපවර්තනය"</string>
@@ -1847,6 +1855,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"කාර්යාල පැතිකඩ ක්‍රියාත්මක කරන්නද?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"ඔබගේ වැඩ යෙදුම්, දැනුම්දීම්, දත්ත සහ වෙනත් කාර්යාල පැතිකඩ විශේෂාංග ක්‍රියාත්මක කරනු ඇත"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ක්‍රියාත්මක කරන්න"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"මෙම යෙදුම Android හි පැරණි අනුවාදයක් සඳහා තනා ඇති අතර නිසියාකාරව ක්‍රියා නොකරනු ඇත. යාවත්කාලීන සඳහා පරික්ෂා කිරීම උත්සාහ කරන්න, නැතහොත් සංවර්ධක අමතන්න."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"යාවත්කාලීන සඳහා පරික්ෂා කරන්න"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"ඔබට නව පණිවිඩ තිබේ"</string>
@@ -1957,13 +1969,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"බැටරිය සුපුරුදු ආරෝපණයට පෙර ඉවර විය හැක"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"බැටරි සුරැකුම බැටරි ආයු කාලය දීර්ඝ කිරීමට සක්‍රිය කෙරිණි"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"බැටරි සුරැකුම"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"බැටරිය නැවතත් අඩු වන තෙක් බැටරි සුරැකුම යළි ක්‍රියාත්මක නොවේ"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"බැටරිය ප්‍රමාණවත් මට්ටමකට ආරෝපණ කර ඇත. බැටරිය නැවතත් අඩු වන තෙක් බැටරි සුරැකුම යළි ක්‍රියාත්මක නොවේ"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> දුරකථනය ආරෝපණ විය"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ටැබ්ලටය ආරෝපණ කළා"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> උපාංගය ආරෝපණ විය"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"බැටරි සුරැකුම අක්‍රියයි. විශේෂාංග තවදුරටත් සීමිත නොවේ."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"බැටරි සුරැකුම අක්‍රියයි. විශේෂාංග තවදුරටත් සීමිත නොවේ."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ෆෝල්ඩරය"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android යෙදුම"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ගොනුව"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 6bf54b0..f48368f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"prístup ku kalendáru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"posielanie a zobrazovanie SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Úložisko"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"prístup k fotkám, médiám a súborom v zariadení"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofón"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávanie zvuku"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Je možné použiť klepnutie, prejdenie, stiahnutie prstami a ďalšie gestá."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestá odtlačkom prsta"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dokáže zaznamenať gestá na senzore odtlačkov prstov zariadenia."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"zakázanie alebo zmeny stavového riadka"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Umožňuje aplikácii vypnúť stavový riadok alebo pridať a odstrániť systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vydávanie sa za stavový riadok"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšiť hlasitosť nad odporúčanú úroveň?\n\nDlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použiť skratku dostupnosti?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Keď je skratka zapnutá, stlačením obidvoch tlačidiel hlasitosti na tri sekundy spustíte funkciu dostupnosti.\n\n Aktuálna funkcia dostupnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciu môžete zmeniť v časti Nastavenia &gt; Dostupnosť."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Prázdne"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Upraviť skratky"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Zrušiť"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vypnúť skratku"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Zapnúť pracovný profil?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Pracovné aplikácie, upozornenia, dáta a ďalšie funkcie pracovného profilu sa zapnú"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Zapnúť"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Táto aplikácia bola zostavená pre staršiu verziu Androidu a nemusí správne fungovať. Skúste skontrolovať dostupnosť aktualizácií alebo kontaktovať vývojára."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Skontrolovať dostupnosť aktualizácie"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové správy."</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batéria sa môže vybiť pred obvyklým nabitím"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Bol aktivovaný šetrič batérie na predĺženie výdrže batérie"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Šetrič batérie"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Šetrič batérie sa znova aktivuje až pri nízkej úrovni nabitia batérie"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batéria bola nabitá na dostatočnú úroveň. Šetrič batérie sa znova aktivuje až pri nízkej úrovni nabitia batérie."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Úroveň nabitia telefónu: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Úroveň nabitia tabletu: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Úroveň nabitia zariadenia: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Šetrič batérie je vypnutý. Funkcie už nie sú obmedzené."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Šetrič batérie bol vypnutý. Funkcie už nie sú obmedzené."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Priečinok"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikácia pre Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Súbor"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7aa91f7..6343e0e 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostop do koledarja"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"pošiljanje in ogled sporočil SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Shramba"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"dostop do fotografij, predstavnosti in datotek v napravi"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snemanje zvoka"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Mogoče je izvajanje dotikov, vlečenja, primikanja in razmikanja prstov ter drugih potez."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Poteze po tipalu prstnih odtisov"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Prepoznava poteze, narejene po tipalu prstnih odtisov naprave."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogočanje ali spreminjanje vrstice stanja"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Aplikacijam omogoča onemogočenje vrstice stanja ali dodajanje in odstranjevanje ikon sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"postane vrstica stanja"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ali želite povečati glasnost nad priporočeno raven?\n\nDolgotrajno poslušanje pri veliki glasnosti lahko poškoduje sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite uporabljati bližnjico funkcij za ljudi s posebnimi potrebami?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Ko je bližnjica vklopljena, pritisnite gumba za glasnost in ju pridržite tri sekunde, če želite zagnati funkcijo za ljudi s posebnimi potrebami.\n\n Trenutna funkcija za ljudi s posebnimi potrebami:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkcijo lahko spremenite v »Nastavitve &gt; Funkcije za ljudi s posebnimi potrebami«."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Prazno"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi bližnjice"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Prekliči"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Izklopi bližnjico"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Uporabi bližnjico"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Želite vklopiti delovni profil?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Vklopili boste svoje delovne aplikacije, obvestila, podatke in druge funkcije delovnega profila"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Vklop"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ta aplikacija je bila zasnovana za starejšo različico Androida in morda ne bo delovala pravilno. Preverite, ali so na voljo posodobitve, ali pa se obrnite na razvijalca."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Preveri, ali je na voljo posodobitev"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nova sporočila."</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumulator se bo morda izpraznil, preden ga običajno priključite na polnjenje"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Vklopilo se je varčevanje z energijo akumulatorja za podaljšanje časa delovanja akumulatorja"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Varčevanje z energijo akumulatorja"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Varčevanje z energijo akumulatorja se ne bo znova aktiviralo, dokler akumulator ne bo znova skoraj prazen"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Akumulator je dovolj napolnjen. Varčevanje z energijo akumulatorja se ne bo znova aktiviralo, dokler akumulator ne bo znova skoraj prazen."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Napolnjenost telefona: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Napolnjenost tabličnega računalnika: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Napolnjenost naprave: <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Varčevanje z energijo akumulatorja je izklopljeno. Funkcije niso več omejene."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Varčevanje z energijo akumulatorja je izklopljeno. Funkcije niso več omejene."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Mapa"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikacija za Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Datoteka"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index f38d354..ceba0be 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"qasje te kalendari yt"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"dërgo dhe shiko mesazhet SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Hapësira e ruajtjes"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"qasjen te fotografitë, përmbajtjet audio-vizuale dhe skedarët në pajisje"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"regjistro audio"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Mund të trokasë, rrëshqasë, bashkojë gishtat dhe kryejë gjeste të tjera."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gjestet e gjurmës së gishtit"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Mund të regjistrojë gjestet e kryera në sensorin e gjurmës së gishtit të pajisjes."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"çaktivizo ose modifiko shiritin e statusit"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Lejon aplikacionin të çaktivizojë shiritin e statusit dhe të heqë ikonat e sistemit."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"të bëhet shiriti i statusit"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Të ngrihet volumi mbi nivelin e rekomanduar?\n\nDëgjimi me volum të lartë për periudha të gjata mund të dëmtojë dëgjimin."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Të përdoret shkurtorja e qasshmërisë?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kur shkurtorja është e aktivizuar, shtypja e të dy butonave për 3 sekonda do të nisë një funksion qasshmërie.\n\n Funksioni aktual i qasshmërisë:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Mund ta ndryshosh funksionin te Cilësimet &gt; Qasshmëria."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Boshatis"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redakto shkurtoret"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Anulo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Çaktivizo shkurtoren"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kthimi i ngjyrës"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Të aktivizohet profili i punës?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacionet e punës, njoftimet, të dhënat e tua dhe funksionet e tjera të profilit të punës do të aktivizohen"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivizo"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ky aplikacion është ndërtuar për një version më të vjetër të Android dhe mund të mos funksionojë mirë. Provo të kontrollosh për përditësime ose kontakto me zhvilluesin."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kontrollo për përditësim"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Ke mesazhe të reja"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria mund të mbarojë përpara ngarkimit të zakonshëm"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"\"Kursyesi i baterisë\" u aktivizua për të zgjatur jetëgjatësinë e baterisë"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Kursyesi i baterisë"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"\"Kursyesi i baterisë\" nuk do të aktivizohet përsëri derisa bateria të jetë përsëri në nivel të ulët"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Bateria është karikuar në një nivel të mjaftueshëm. \"Kursyesi i baterisë\" nuk do të aktivizohet përsëri deri sa bateria të jetë përsëri në nivel të ulët."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefoni është karikuar në <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tableti është karikuar në <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Pajisja është karikuar në <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"\"Kursyesi i baterisë\" është joaktiv. Funksionet nuk janë më të kufizuara."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"\"Kursyesi i baterisë\" është çaktivizuar. Funksionet nuk janë më të kufizuara."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Dosje"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Aplikacion i Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Skedar"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index c3881cb..f3a2ce5 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -290,7 +290,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"приступи календару"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"шаље и прегледа SMS поруке"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Меморијски простор"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Датотеке и медији"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"приступа сликама, медијима и датотекама на уређају"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима звук"</string>
@@ -316,6 +316,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Може да додирује, листа, скупља приказ и обавља друге покрете."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Покрети за отисак прста"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да региструје покрете на сензору за отисак прста на уређају."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Направи снимак екрана"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да направи снимак екрана."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"онемогућавање или измена статусне траке"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"функционисање као статусна трака"</string>
@@ -1632,6 +1634,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Желите ли да користите пречицу за приступачност?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Када је пречица укључена, притисните оба дугмета за јачину звука да бисте покренули функцију приступачности.\n\n Актуелна функција приступачности:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Можете да промените функцију у одељку Подешавања &gt; Приступачност."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Празно"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Измените пречице"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Откажи"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Искључи пречицу"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string>
@@ -1877,6 +1882,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Да укључимо профил за Work?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Укључиће се пословне апликације, обавештења, подаци и друге функције профила за Work"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Укључи"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Апликација није доступна"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> тренутно није доступна."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ова апликација је направљена за старију верзију Android-а, па можда неће радити исправно. Потражите ажурирања или контактирајте програмера."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Потражи ажурирање"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нове поруке"</string>
@@ -1988,13 +1995,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерија ће се можда испразнити пре уобичајеног пуњења"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Уштеда батерије је активирана да би се продужило трајање батерије"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Уштеда батерије"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Уштеда батерије се неће поново активирати док батерија не буде скоро празна"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батерија је напуњена до задовољавајућег нивоа. Уштеда батерије се неће поново активирати док батерија не буде скоро празна."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефон је напуњен <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Таблет је напуњен <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Уређај је напуњен <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Уштеда батерије је искључена. Функције више нису ограничене."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Уштеда батерије је искључена. Функције више нису ограничене."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Уштеда батерије је искључена"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Батерија телефона је довољно напуњена. Функције више нису ограничене."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Батерија таблета је довољно напуњена. Функције више нису ограничене."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Батерија уређаја је довољно напуњена. Функције више нису ограничене."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Директоријум"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android апликација"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Датотека"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index feef35b..ade5e6a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"få tillgång till din kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"skicka och visa sms"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Lagring"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Filer och media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"få åtkomst till foton, media och filer på din enhet"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"spela in ljud"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan trycka, svepa, nypa och göra andra rörelser."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Fingeravtrycksrörelser"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan registrera rörelser som utförs med hjälp av enhetens fingeravtryckssensor."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skärmdump"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Du kan ta en skärmdump av skärmen."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"inaktivera eller ändra statusfält"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Tillåter att appen inaktiverar statusfältet eller lägger till och tar bort systemikoner."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"visas i statusfältet"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vill du höja volymen över den rekommenderade nivån?\n\nAtt lyssna med stark volym långa stunder åt gången kan skada hörseln."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vill du använda Aktivera tillgänglighet snabbt?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"När kortkommandot har aktiverats startar du en tillgänglighetsfunktion genom att trycka ned båda volymknapparna i tre sekunder.\n\n Aktuell tillgänglighetsfunktion:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kan ändra funktionen i Inställningar &gt; Tillgänglighet."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Töm"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redigera genvägar"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Avbryt"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Inaktivera kortkommandot"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Använd kortkommandot"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverterade färger"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Vill du aktivera jobbprofilen?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Jobbappar, aviseringar, data och andra funktioner i jobbprofilen aktiveras"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivera"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Appen är inte tillgänglig"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> är inte tillgängligt just nu."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Appen har utvecklats för en äldre version av Android och kanske inte fungerar som den ska. Testa att söka efter uppdateringar eller kontakta utvecklaren."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sök efter uppdateringar"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nya meddelanden"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batteriet kan ta slut innan du brukar ladda det"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparläget har aktiverats för att utöka batteritiden"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparläge"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Batterisparläget aktiveras inte igen förrän batterinivån är låg"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batteriet har laddats tillräckligt. Batterisparläget aktiveras inte igen förrän batterinivån är låg."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Mobilen är laddad till <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Surfplattan är laddad till <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Enheten är laddad till <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Batterisparläget har inaktiverats. Funktioner begränsas inte längre."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Batterisparläget har inaktiverats. Funktioner begränsas inte längre."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Batterisparläget har inaktiverats"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonen har laddats tillräckligt. Funktioner begränsas inte längre."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Surfplattan har laddats tillräckligt. Funktioner begränsas inte längre."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Enheten har laddats tillräckligt. Funktioner begränsas inte längre."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Mapp"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android-app"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fil"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 094e324..f893af3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ifikie kalenda yako"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"itume na iangalie SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Hifadhi"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"ifikie picha, maudhui na faili kwenye kifaa chako"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Kipokea sauti"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"irekodi sauti"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Unaweza kugusa, kutelezesha kidole, kubana na kutekeleza ishara zingine."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Ishara za alama ya kidole"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Inaweza kurekodi ishara zinazotekelezwa kwenye kitambua alama ya kidole."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"zima au rekebisha mwambaa hali"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa aikoni za mfumo."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"kuwa sehemu ya arifa"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ungependa kupandisha sauti zaidi ya kiwango kinachopendekezwa?\n\nKusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ungependa kutumia njia ya mkato ya ufikivu?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Unapowasha kipengele cha njia ya mkato, hatua ya kubonyeza vitufe vyote viwili vya sauti kwa dakika 3 itafungua kipengele cha ufikivu.\n\n Kipengele cha ufikivu kilichopo kwa sasa:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Unaweza kubadilisha kipengele hiki katika Mipangilio &gt; Zana za ufikivu."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Tupu"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Kubadilisha njia za mkato"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Ghairi"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Zima kipengele cha Njia ya Mkato"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tumia Njia ya Mkato"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ungependa kuwasha wasifu wa kazini?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Hatua hii itawasha data, arifa, programu za kazini, arifa na vipengele vingine vya wasifu wa kazini"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Washa"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Programu hii iliundwa kwa ajili ya toleo la zamani la Android na huenda isifanye kazi vizuri. Jaribu kuangalia masasisho au uwasiliane na msanidi programu."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Angalia masasisho"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Una ujumbe mpya"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Huenda betri itakwisha chaji mapema"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Imewasha Kiokoa Betri ili kurefusha muda wa matumizi ya betri"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Kiokoa betri"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Kiokoa betri hakitawashwa tena hadi chaji ipungue tena"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Betri imejazwa chaji hadi kiwango cha kutosha. Kiokoa betri hakitawashwa tena hadi chaji ya betri ipungue tena."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Simu ina <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ya chaji"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Kompyuta kibao ina <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ya chaji"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Kifaa kina <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ya chaji"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Kiokoa betri kimezimwa. Vipengele havizuiliwi tena."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Kiokoa betri kimezimwa. Vipengele havizuiliwi tena."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Folda"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Programu ya Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Faili"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 08b32b9..d3a4613 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"கேலெண்டரை அணுகலாம்"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS அனுப்பலாம், வந்த SMSகளைப் பார்க்கலாம்"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"சேமிப்பிடம்"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"உங்கள் சாதனத்தில் உள்ள படங்கள், மீடியா மற்றும் கோப்புகளை அணுக வேண்டும்"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"மைக்ரோஃபோன்"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ஒலிப் பதிவு செய்யலாம்"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"தட்டலாம், ஸ்வைப் செய்யலாம், பின்ச் செய்யலாம் மற்றும் பிற சைகைகளைச் செயல்படுத்தலாம்."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"கைரேகை சைகைகள்"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"சாதனத்தின் கைரேகை சென்சார்மேல் செய்யப்படும் சைகைகளைக் கேப்ட்சர் செய்ய முடியும்."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"நிலைப் பட்டியை முடக்குதல் அல்லது மாற்றுதல்"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"நிலைப் பட்டியை முடக்க அல்லது முறைமையில் ஐகான்களைச் சேர்க்க மற்றும் அகற்ற ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"நிலைப் பட்டியில் இருக்கும்"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது கேட்கும் திறனைப் பாதிக்கலாம்."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"அணுகல்தன்மை ஷார்ட்கட்டைப் பயன்படுத்தவா?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ஷார்ட்கட் இயக்கத்தில் இருந்தால், இரண்டு ஒலியளவு பொத்தான்களையும் 3 வினாடிகள் அழுத்தி, அணுகல்தன்மை அம்சத்தை இயக்கலாம்.\n\n தற்போதைய அணுகல்தன்மை அம்சம்:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n அமைப்புகள் &gt; அணுகல்தன்மை என்பதற்குச் சென்று, அம்சத்தை மாற்றலாம்."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"காலியானது"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ஷார்ட்கட்களை மாற்று"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ரத்துசெய்"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ஷார்ட்கட்டை முடக்கு"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ஷார்ட்கட்டைப் பயன்படுத்து"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"வண்ணத்தை நேர் எதிராக மாற்றுதல்"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"பணிச் சுயவிவரத்தை ஆன் செய்யவா?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"பணி ஆப்ஸ், அறிவிப்புகள், தரவு மற்றும் பிற பணிச் சுயவிவர அம்சங்கள் ஆன் செய்யப்படும்"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"இயக்கு"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"இந்த ஆப்ஸ் Android இன் பழைய பதிப்புக்காக உருவாக்கப்பட்டதால், சரியாக வேலை செய்யாமல் போகலாம். புதுப்பிப்புகள் ஏதேனும் உள்ளதா எனப் பார்க்கவும் அல்லது டெவெலப்பரைத் தொடர்புகொள்ளவும்."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"புதுப்பிப்பு உள்ளதா எனப் பார்"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"புதிய செய்திகள் வந்துள்ளன"</string>
@@ -1855,11 +1867,9 @@
     <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> உடன் இணைக்கப்பட்டது"</string>
     <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"கோப்புகளைப் பார்க்க, தட்டவும்"</string>
     <string name="pin_target" msgid="8036028973110156895">"பின் செய்"</string>
-    <!-- no translation found for pin_specific_target (7824671240625957415) -->
-    <skip />
+    <string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> ஐப் பின் செய்"</string>
     <string name="unpin_target" msgid="3963318576590204447">"பின்னை அகற்று"</string>
-    <!-- no translation found for unpin_specific_target (3859828252160908146) -->
-    <skip />
+    <string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> ஐப் பின் நீக்கு"</string>
     <string name="app_info" msgid="6113278084877079851">"ஆப்ஸ் தகவல்"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="6577581216125805905">"டெமோவைத் தொடங்குகிறது…"</string>
@@ -1957,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"பேட்டரி சேமிப்பான்"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"பேட்டரி மறுபடியும் குறையும் வரை பேட்டரி சேமிப்பானை இயக்க இயலாது"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"பேட்டரி போதுமான அளவு சார்ஜ் செய்யப்பட்டுள்ளது. பேட்டரி குறையும் வரை பேட்டரி சேமிப்பானை மீண்டும் இயக்க இயலாது."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"மொபைல் <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> சார்ஜ் செய்யப்பட்டது"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"டேப்லெட் <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> சார்ஜ் செய்யப்பட்டது"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"சாதனம் <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> சார்ஜ் செய்யப்பட்டது"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"பேட்டரி சேமிப்பான் ஆஃப் செய்யப்பட்டுள்ளது. அம்சங்கள் இனி தடையின்றி இயங்கும்."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"பேட்டரி சேமிப்பான் ஆஃப் செய்யப்பட்டுள்ளது. அம்சங்கள் இனி தடையின்றி இயங்கும்."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"கோப்புறை"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ஆப்ஸ்"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ஃபைல்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index e1b88ac..04a4d41 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"మీ క్యాలెండర్‌ను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS సందేశాలను పంపడం మరియు వీక్షించడం"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"నిల్వ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్‌లను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"మైక్రోఫోన్"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ఆడియోను రికార్డ్ చేయడానికి"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"నొక్కగలరు, స్వైప్ చేయగలరు, స్క్రీన్‌పై రెండు వేళ్లను ఉంచి ఆ వేళ్లను దగ్గరకు లేదా దూరానికి లాగగలరు మరియు ఇతర సంజ్ఞలను చేయగలరు."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"వేలిముద్ర సంజ్ఞలు"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"పరికర వేలిముద్ర సెన్సార్‌లో ఉపయోగించిన సంజ్ఞలను క్యాప్చర్ చేయవచ్చు."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"స్థితి బార్‌ను నిలిపివేయడం లేదా సవరించడం"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"స్థితి బార్‌ను నిలిపివేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"స్థితి పట్టీగా ఉండటం"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"షార్ట్‌కట్ ఆన్‌లో ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కితే యాక్సెస్ సామర్థ్య ఫీచర్ ప్రారంభం అవుతుంది.\n\n ప్రస్తుత యాక్సెస్ సామర్థ్య ఫీచర్:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n సెట్టింగ్‌లు &gt; యాక్సెస్ సామర్థ్యంలో మీరు ఫీచర్‌ను మార్చవచ్చు."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ఖాళీ"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"షార్ట్‌కట్‌లను ఎడిట్ చేయి"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"రద్దు చేయి"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"సత్వరమార్గాన్ని ఆఫ్ చేయి"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"సత్వరమార్గాన్ని ఉపయోగించు"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"రంగుల మార్పిడి"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"కార్యాలయ ప్రొఫైల్‌ని ఆన్ చేయాలా?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"మీ కార్యాలయ యాప్‌లు, నోటిఫికేషన్‌లు, డేటా మరియు ఇతర కార్యాలయ ప్రొఫైల్ ఫీచర్‌లు ఆన్ చేయబడతాయి"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"ఆన్ చేయి"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం తనిఖీ చేయండి"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త సందేశాలు ఉన్నాయి"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"మామూలుగా ఛార్జ్ చేసేలోపు బ్యాటరీ ఖాళీ కావచ్చు"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి బ్యాటరీ సేవర్ యాక్టివేట్ చేయబడింది"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"బ్యాటరీ సేవర్"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"బ్యాటరీ మళ్లీ తగ్గిపోయే వరకు బ్యాటరీ సేవర్ తిరిగి యాక్టివేట్ చేయబడదు"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"బ్యాటరీ సరిపడే స్థాయికి ఛార్జ్ చేయబడింది. బ్యాటరీ మళ్లీ తగ్గిపోయే వరకు బ్యాటరీ సేవర్ తిరిగి యాక్టివేట్ చేయబడదు."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"ఫోన్ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ఛార్జ్ అయింది"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"టాబ్లెట్ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ఛార్జ్ అయింది"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"పరికరం <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ఛార్జ్ అయింది"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"బ్యాటరీ సేవర్ ఆఫ్‌లో ఉంది. ఫీచర్‌లు ఇప్పటి నుండి పరిమితం చేయబడవు."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"బ్యాటరీ సేవర్ ఆఫ్ చేయబడింది. ఫీచర్‌లు ఇప్పటి నుండి పరిమితం చేయబడవు."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"ఫోల్డర్"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android అప్లికేషన్"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ఫైల్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index bd02a73..11aa407 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"เข้าถึงปฏิทิน"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ส่งและดูข้อความ SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"พื้นที่เก็บข้อมูล"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"เข้าถึงรูปภาพ สื่อ และไฟล์บนอุปกรณ์ของคุณ"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"ไมโครโฟน"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"บันทึกเสียง"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"สามารถแตะ เลื่อน บีบ และทำท่าทางสัมผัสอื่นๆ"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"ท่าทางสัมผัสลายนิ้วมือ"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"สามารถจับท่าทางสัมผัสที่เกิดขึ้นบนเซ็นเซอร์ลายนิ้วมือของอุปกรณ์"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"ปิดการใช้งานหรือแก้ไขแถบสถานะ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"อนุญาตให้แอปพลิเคชันปิดใช้งานแถบสถานะหรือเพิ่มและนำไอคอนระบบออก"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"เป็นแถบสถานะ"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"นี่เป็นการเพิ่มระดับเสียงเกินระดับที่แนะนำ\n\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ใช้ทางลัดการช่วยเหลือพิเศษไหม"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มเป็นเวลา 3 วินาทีจะเริ่มฟีเจอร์การช่วยเหลือพิเศษ\n\n ฟีเจอร์การช่วยเหลือพิเศษปัจจุบัน:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n คุณสามารถเปลี่ยนฟีเจอร์ในการตั้งค่า &gt; การช่วยเหลือพิเศษ"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"ล้าง"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"แก้ไขทางลัด"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ยกเลิก"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ปิดทางลัด"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ใช้ทางลัด"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"การกลับสี"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"เปิดโปรไฟล์งานไหม"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"ระบบจะเปิดแอปงาน การแจ้งเตือน ข้อมูล และฟีเจอร์อื่นๆ ในโปรไฟล์งาน"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"เปิด"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"แอปนี้สร้างขึ้นเพื่อ Android เวอร์ชันเก่าและอาจทำงานผิดปกติ โปรดลองตรวจหาการอัปเดตหรือติดต่อนักพัฒนาซอฟต์แวร์"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ตรวจสอบอัปเดต"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"คุณมีข้อความใหม่"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"แบตเตอรี่อาจหมดก่อนการชาร์จปกติ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"เปิดใช้งานโหมดประหยัดแบตเตอรี่แล้วเพื่อยืดอายุการใช้งานแบตเตอรี่"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"โหมดประหยัดแบตเตอรี่"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"โหมดประหยัดแบตเตอรี่จะไม่เปิดใช้งานอีกจนกว่าแบตเตอรี่จะเหลือน้อยอีกครั้ง"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"ชาร์จแบตเตอรี่จนถึงระดับที่เพียงพอแล้ว โหมดประหยัดแบตเตอรี่จะไม่เปิดใช้งานอีกจนกว่าแบตเตอรี่จะเหลือน้อยอีกครั้ง"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"โทรศัพท์ชาร์จ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"แท็บเล็ตชาร์จ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"อุปกรณ์ชาร์จ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"โหมดประหยัดแบตเตอรี่ปิดอยู่ ไม่มีการจำกัดฟีเจอร์แล้ว"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"ปิดโหมดประหยัดแบตเตอรี่แล้ว ไม่มีการจำกัดฟีเจอร์แล้ว"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"โฟลเดอร์"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"ไฟล์แอปพลิเคชัน Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"ไฟล์"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c6fb52d..718e170 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"i-access ang iyong kalendaryo"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"magpadala at tumingin ng mga mensaheng SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Storage"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"i-access ang mga larawan, media at file sa iyong device"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikropono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"mag-record ng audio"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"May kakayahang mag-tap, mag-swipe, mag-pinch at magsagawa ng iba pang mga galaw."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Mga galaw gamit ang fingerprint"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Makukunan ang mga galaw na ginawa sa sensor para sa fingerprint ng device."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"i-disable o baguhin ang status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Pinapayagan ang app na i-disable ang status bar o magdagdag at mag-alis ng mga icon ng system."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"maging status bar"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lakasan ang volume nang lagpas sa inirerekomendang antas?\n\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gagamitin ang Shortcut sa Pagiging Accessible?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kapag naka-on ang shortcut, magsisimula ang isang feature ng pagiging naa-access kapag pinindot ang parehong button ng volume sa loob ng 3 segundo.\n\n Kasalukuyang feature ng pagiging naa-access:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Maaari mong baguhin ang feature sa Mga Setting &gt; Pagiging Accessible."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Bakantehin"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"I-edit ang mga shortcut"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Kanselahin"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"I-off ang Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"I-on ang profile sa trabaho?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Mao-on ang iyong mga app sa trabaho, notification, data, at iba pang feature sa profile sa trabaho"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"I-on"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ang app na ito ay ginawa para sa mas lumang bersyon ng Android at maaaring hindi gumana nang maayos. Subukang tingnan kung may mga update, o makipag-ugnayan sa developer."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tingnan kung may update"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Mayroon kang mga bagong mensahe"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Maaaring maubos ang baterya bago ang karaniwang pag-charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pangtipid sa Baterya para patagalin ang buhay ng baterya"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pangtipid sa Baterya"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Hindi muling maa-activate ang Pangtipid sa Baterya hangga\'t hindi pa ulit mababa ang baterya"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Na-charge na ang baterya sa sapat na antas. Hindi muling maa-activate ang Pangtipid sa Baterya hangga\'t hindi pa ulit mababa ang baterya."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ang charge ng telepono"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ang charge ng tablet"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> ang charge ng baterya"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Na-off ang Pangtipid sa Baterya. Hindi na pinaghihigpitan ang mga feature."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Na-off ang Pangtipid sa Baterya. Hindi na pinaghihigpitan ang mga feature."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Folder"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android application"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"File"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 25d0674..93d9af1 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"takviminize erişme"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS mesajları gönderme ve görüntüleme"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Depolama"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"cihazınızdaki fotoğraflara, medyaya ve dosyalara erişme"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ses kaydetme"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Dokunabilir, hızlıca kaydırabilir, sıkıştırabilir ve diğer hareketleri yapabilirsiniz."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Parmak izi hareketleri"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Cihazın parmak izi sensörlerinde gerçekleştirilen hareketleri yakalayabilir."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"durum çubuğunu devre dışı bırak veya değiştir"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"durum çubuğunda olma"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ses seviyesi önerilen düzeyin üzerine yükseltilsin mi?\n\nUzun süre yüksek ses seviyesinde dinlemek işitme duyunuza zarar verebilir."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erişilebilirlik Kısayolu Kullanılsın mı?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kısayol açık olduğunda, ses düğmelerinin ikisini birden 3 saniyeliğine basılı tutmanız bir erişilebilirlik özelliğini başlatır.\n\n Geçerli erişilebilirlik özelliği:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Özelliği, Ayarlar &gt; Erişilebilirlik seçeneğinden değiştirebilirsiniz."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Boş"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Kısayolları düzenle"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"İptal"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Kısayolu Kapat"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"İş profili açılsın mı?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"İş uygulamalarınız, bildirimleriniz, verileriniz ve diğer iş profili özellikleriniz açılacak"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Aç"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu uygulama Android\'in daha eski bir sürümü için oluşturuldu ve düzgün çalışmayabilir. Güncellemeleri kontrol etmeyi deneyin veya geliştiriciyle iletişime geçin."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncellemeleri denetle"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pil normal şarjdan önce bitebilir"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Pilin ömrünü uzatmak için Pil Tasarrufu etkinleştirildi"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pil Tasarrufu"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Pil seviyesi tekrar azalıncaya kadar Pil Tasarrufu yeniden etkinleştirilmeyecek"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Pil yeterli bir seviyede şarj edildi. Pil seviyesi tekrar azalıncaya kadar Pil Tasarrufu yeniden etkinleştirilmeyecek."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> şarja sahip"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Tablet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> şarja sahip"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Cihaz <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> şarja sahip"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Pil Tasarrufu kapalı. Özellikler artık kısıtlanmış değil."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Pil Tasarrufu kapalı. Özellikler artık kısıtlanmış değil."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Klasör"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android uygulaması"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Dosya"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ca0146b..0f8b368 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -293,7 +293,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"отримувати доступ до календаря"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"надсилати та переглядати SMS-повідомлення"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Пам’ять"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"отримувати доступ до фотографій, мультимедійного вмісту та файлів на вашому пристрої"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Мікрофон"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"записувати аудіо"</string>
@@ -319,6 +320,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Можна торкатися, проводити пальцем, стискати пальці та виконувати інші жести."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Жести на сканері відбитків пальців"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може фіксувати жести на сканері відбитків пальців."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"вимикати чи змін. рядок стану"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозволяє програмі вимикати рядок стану чи додавати та видаляти піктограми системи."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"відображатися як рядок стану"</string>
@@ -1654,6 +1659,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Збільшити гучність понад рекомендований рівень?\n\nЯкщо слухати надто гучну музику тривалий час, можна пошкодити слух."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Використовувати швидке ввімкнення?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Коли ярлик увімкнено, після натискання обох клавіш гучності й утримування їх протягом 3 секунд увімкнеться функція спеціальних можливостей.\n\n Поточна функція спеціальних можливостей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Цю функцію можна змінити в меню \"Налаштування\" &gt; \"Спеціальні можливості\"."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Очистити"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Редагувати засоби"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Скасувати"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Вимкнути ярлик"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Використовувати ярлик"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія кольорів"</string>
@@ -1909,6 +1917,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Увімкнути робочий профіль?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Додатки, сповіщення, дані й інші функції робочого профілю буде ввімкнено"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Увімкнути"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Цей додаток створений для старішої версії Android і може працювати неналежним чином. Спробуйте знайти оновлення або зв’яжіться з розробником."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шукати оновлення"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"У вас є нові повідомлення"</string>
@@ -2021,13 +2033,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Акумулятор може розрядитися раніше ніж зазвичай"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Режим енергозбереження активовано для збільшення часу роботи акумулятора"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Режим енергозбереження"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Режим енергозбереження не ввімкнеться, доки рівень заряду знову не знизиться"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Акумулятор заряджено достатньо. Режим енергозбереження буде знову ввімкнено, коли рівень заряду знизиться."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Телефон заряджено на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Планшет заряджено на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Пристрій заряджено на <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Режим енергозбереження вимкнено. Функції вже не обмежено."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Режим енергозбереження вимкнено. Функції вже не обмежено."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Папка"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Додаток Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Файл"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 1d79c6e..5b957159 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏SMS پیغامات بھیجیں اور دیکھیں"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"اسٹوریج"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"آپ کے آلہ پر تصاویر، میڈیا اور فائلوں تک رسائی حاصل کر سکتی ہیں"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"مائکروفون"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"آڈیو ریکارڈ کریں"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"تھپتھپانا، سوائپ کرنا، چٹکی بھرنا اور دیگر اشارے انجام دے سکتی ہے"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"فنگر پرنٹ کے اشارے"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"آلہ کے فنگر پرنٹ سینسر پر کیے گئے اشاروں کو کیپچر کر سکتا ہے۔"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"بطور اسٹیٹس بار کام لیں"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"والیوم کو تجویز کردہ سطح سے زیادہ کریں؟\n\nزیادہ وقت تک اونچی آواز میں سننے سے آپ کی سماعت کو نقصان پہنچ سکتا ہے۔"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ایکسیسبیلٹی شارٹ کٹ استعمال کریں؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"شارٹ کٹ آن ہونے پر، 3 سیکنڈ تک دونوں والیوم بٹنز کو دبانے سے ایک ایکسیسبیلٹی خصوصیت شروع ہو جائے گی۔\n\n موجودہ ایکسیسبیلٹی خصوصیت:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n آپ خصوصیت کو ترتیبات &gt; ایکسیسبیلٹی میں جا کر تبدیل کر سکتے ہیں۔"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"خالی"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"شارٹ کٹس میں ترمیم کریں"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"منسوخ کریں"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"شارٹ کٹ آف کریں"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"شارٹ کٹ استعمال کریں"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"رنگوں کی تقلیب"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"دفتری پروفائل آن کریں؟"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"آپ کی دفتری ایپس، اطلاعات، ڈیٹا اور دفتری پروفائل کی دیگر خصوصیات آن کر دی جائیں گی"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"آن کریں"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏یہ ایپ Android کے پرانے ورژن کے لئے بنائی گئی ہے اور ہو سکتا ہے صحیح طور پر کام نہ کرے۔ اپ ڈیٹس چیک کر کے آزمائیں یا ڈیولپر سے رابطہ کریں۔"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"اپ ڈیٹ چیک کریں"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"آپ کے پاس نئے پیغامات ہیں"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"معمول چارج سے پہلے بیٹری ختم ہو سکتی ہے"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"بیٹری لائف کو بڑھانے کے لیے بیٹری سیور کو فعال کر دیا گیا ہے"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"بیٹری سیور"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"بیٹری سیور اس وقت تک دوبارہ فعال نہیں ہوگی جب تک پھر سے بیٹری کم نہیں ہو جاتی ہے"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"بیٹری کافی سطح تک چارج ہو گئی ہے۔ بیٹری سیور اس وقت تک دوبارہ فعال نہیں ہوگی جب تک پھر سے بیٹری کم نہیں ہو جاتی ہے۔"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"فون <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> چارج ہو گیا"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"ٹیبلیٹ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> چارج ہو گیا"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"آلہ <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> چارج ہو گیا"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"بیٹری سیور آف ہے۔ خصوصیات پر اب پابندی نہیں ہے۔"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"بیٹری سیور کو آف کر دیا گیا۔ خصوصیات پر اب پابندی نہیں ہے۔"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"فولڈر"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"‏Android ایپلیکیشن"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"فائل"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 744f54d..c837414 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"taqvimingizga kirish"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS xabarlarni yuborish va ko‘rish"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Xotira"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Fayllar va media"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"qurilmangizdagi surat, multimedia va fayllarga kirish"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ovoz yozib olish"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Bosish, surish; jipslashtirish va boshqa imo-ishoralarni amalga oshirish mumkin."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Barmoq izi ishoralari"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Barmoq izi skanerida kiritilgan ishoralarni taniy oladi."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Skrinshot olish"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekrandan skrinshot olishi mumkin."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"holat panelini o‘zgartirish yoki o‘chirish"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ilova holat panelini o‘chirib qo‘yishi hamda tizim ikonkalarini qo‘shishi yoki olib tashlashi mumkin."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"holat qatorida ko‘rinishi"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Tovush balandligi tavsiya etilgan darajadan ham yuqori qilinsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Tezkor ishga tushirishdan foydalanilsinmi?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Maxsus imkoniyatlar funksiyasidan foydalanish uchun u yoniqligida ikkala ovoz balandligini boshqarish tugmasini 3 soniya bosib turing.\n\n Joriy maxsus imkoniyatlar funksiyasi:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Bu funksiyani Sozlamalar &gt; Maxsus imkoniyatlar orqali o‘zgartirish mumkin."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Boʻshatish"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Tezkor tugmalarni tahrirlash"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Bekor qilish"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Tezkor ishga tushirishni o‘chirib qo‘yish"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tezkor ishga tushirishdan foydalanish"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ranglarni akslantirish"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Ishchi profil yoqilsinmi?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Ishchi ilovalar, bildirishnomalar, ma’lumotlar va boshqa ishchi profil imkoniyatlari yoqiladi"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Yoqish"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Ilova ishlamayapti"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"Ayni vaqtda <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi ishlamayapti."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu ilova eskiroq Android versiyalariga chiqarilgan va xato ishlashi mumkin. Yangilanishlarini tekshiring yoki dasturchi bilan bog‘laning."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Yangilanish borligini tekshirish"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Sizga yangi SMS keldi"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batareya quvvati odatdagidan ertaroq tugashi mumkin"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batareya quvvati uzoqroq ishlashi uchun Tejamkor rejim yoqildi"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Quvvat tejash"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Quvvat tejash rejimi qatareya quvvati kamaymaguncha qayta yoqilmaydi"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Batareya yetarli darajada quvvatlandi. Quvvat tejash rejimi qatareya quvvati kamaymaguncha qayta yoqilmaydi."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Telefon <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> quvvat oldi"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Planshet <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> quvvat oldi"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Qurilma <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> quvvat oldi"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Quvvat tejash rejimi faolsizlantirildi. Funksiyalar endi cheklovlarsiz ishlaydi."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Quvvat tejash rejimi faolsizlantirildi. Funksiyalar endi cheklovlarsiz ishlaydi."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Quvvat tejash rejimi faolsizlantirildi"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon yetarli quvvatlandi. Funksiyalar endi cheklovlarsiz ishlaydi."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Planshet yetarli quvvatlandi. Funksiyalar endi cheklovlarsiz ishlaydi."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Qurilma yetarli quvvatlandi. Funksiyalar endi cheklovlarsiz ishlaydi."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Jild"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android ilova"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fayl"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7e4e264..82662ab 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"truy cập lịch của bạn"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tin nhắn SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"gửi và xem tin nhắn SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Bộ nhớ"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"truy cập ảnh, phương tiện và tệp trên thiết bị của bạn"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrô"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ghi âm"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Có thể nhấn, vuốt, chụm và thực hiện các cử chỉ khác."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Cử chỉ vân tay"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Có thể ghi lại các cử chỉ được thực hiện trên cảm biến vân tay của thiết bị."</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"trở thành thanh trạng thái"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bạn tăng âm lượng lên quá mức khuyên dùng?\n\nViệc nghe ở mức âm lượng cao trong thời gian dài có thể gây tổn thương thính giác của bạn."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sử dụng phím tắt Hỗ trợ tiếp cận?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Khi phím tắt được bật, nhấn cả hai nút âm lượng trong 3 giây sẽ bắt đầu một tính năng trợ năng.\n\n Tính năng trợ năng hiện tại:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Bạn có thể thay đổi tính năng trong Cài đặt &gt; Trợ năng."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Xóa sạch"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Chỉnh sửa phím tắt"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Hủy"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Tắt phím tắt"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sử dụng phím tắt"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Đảo màu"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Bạn muốn bật hồ sơ công việc?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Ứng dụng công việc, thông báo, dữ liệu và các tính năng khác của hồ sơ công việc sẽ được bật"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Bật"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ứng dụng này được xây dựng cho một phiên bản Android cũ hơn và có thể hoạt động không bình thường. Hãy thử kiểm tra các bản cập nhật hoặc liên hệ với nhà phát triển."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kiểm tra bản cập nhật"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Bạn có tin nhắn mới"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pin có thể hết trước khi sạc bình thường"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Trình tiết kiệm pin được kích hoạt để kéo dài thời lượng pin"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Trình tiết kiệm pin"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Trình tiết kiệm pin sẽ chỉ kích hoạt lại khi sắp hết pin"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Pin đã sạc đủ. Trình tiết kiệm pin sẽ chỉ kích hoạt lại khi pin sắp hết."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Điện thoại đã sạc được <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Máy tính bảng đã sạc được <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Thiết bị đã sạc được <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Trình tiết kiệm pin đã tắt. Các tính năng không bị hạn chế nữa."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Trình tiết kiệm pin đã tắt. Các tính năng không bị hạn chế nữa."</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"Thư mục"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Ứng dụng Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Tệp"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6abfda6..101a2ec 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"访问您的日历"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短信"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"发送和查看短信"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"存储空间"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"访问您设备上的照片、媒体内容和文件"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"麦克风"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"录制音频"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"可执行点按、滑动、双指张合等手势。"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"指纹手势"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以捕获在设备指纹传感器上执行的手势。"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"停用或修改状态栏"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"允许应用停用状态栏或者增删系统图标。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"用作状态栏"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要将音量调高到建议的音量以上吗?\n\n长时间保持高音量可能会损伤听力。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用无障碍快捷方式吗?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"开启快捷方式后,同时按下两个音量按钮 3 秒钟即可启动所设定的无障碍功能。\n\n当前设定的无障碍功能:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n如需更改设定的功能,请依次转到“设置”&gt;“无障碍”。"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"清空"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"修改快捷方式"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"取消"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"关闭快捷方式"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快捷方式"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"颜色反转"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"要开启工作资料吗?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"您的工作应用、通知、数据及其他工作资料功能将会开启"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"开启"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"此应用专为旧版 Android 打造,因此可能无法正常运行。请尝试检查更新或与开发者联系。"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"检查更新"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"您有新消息"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"电池电量可能会在您平时的充电时间之前耗尽"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已启用省电模式以延长电池续航时间"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"省电模式"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"电池电量不足时才会再次启用省电模式"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"电池电量已充足。电池电量不足时才会再次启用省电模式。"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"手机已充电到 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"平板电脑已充电到 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"设备已充电到 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"省电模式已关闭。各项功能不再受限。"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"省电模式已关闭,各项功能不再受限。"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"文件夹"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android 应用"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"文件"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 2cc42d7..2929869 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取您的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送和查看短訊"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"儲存空間"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"存取裝置上的相片、媒體和檔案"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"麥克風"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"錄音"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"可以輕按、滑動和兩指縮放,並執行其他手勢。"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"指紋手勢"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以擷取在裝置指紋感應器上執行的手勢。"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"停用或修改狀態列"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"成為狀態列"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙功能快速鍵嗎?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"快速鍵開啟後,同時按住音量按鈕 3 秒,無障礙功能便會啟用。\n\n目前的無障礙功能:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n如要變更功能,請前往「設定」&gt;「無障礙功能」。"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"空白"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"編輯捷徑"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"取消"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"關閉快速鍵"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快速鍵"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"要開啟工作設定檔嗎?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"系統將開啟您的工作應用程式、通知、資料和其他工作設定檔功能"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"開啟"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"此應用程式專為舊版 Android 打造,因此可能無法正常運作。請嘗試檢查更新,或與開發人員聯絡。"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"您有新的訊息"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電量可能會在日常充電前耗盡"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"「省電模式」已啟用,以便延長電池壽命"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"省電模式"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"當再次出現低電量時,省電模式才會重新啟用"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"電池已充至足夠電量。當再次出現低電量時,省電模式才會重新啟用。"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"手機已充電至 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"平板電腦已充電至 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"裝置已充電至 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"已關閉省電模式。各項功能已不再受限。"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"已關閉省電模式。各項功能已不再受限。"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"資料夾"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android 應用程式"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"檔案"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 15aaec1..48ff3f6 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -287,7 +287,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取你的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"簡訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送及查看簡訊"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"儲存空間"</string>
+    <!-- no translation found for permgrouplab_storage (1938416135375282333) -->
+    <skip />
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"存取裝置中的相片、媒體和檔案"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"麥克風"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"錄音"</string>
@@ -313,6 +314,10 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"可使用輕觸、滑動和雙指撥動等手勢。"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"指紋手勢"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以擷取使用者對裝置的指紋感應器執行的手勢。"</string>
+    <!-- no translation found for capability_title_canTakeScreenshot (3895812893130071930) -->
+    <skip />
+    <!-- no translation found for capability_desc_canTakeScreenshot (7762297374317934052) -->
+    <skip />
     <string name="permlab_statusBar" msgid="8798267849526214017">"停用或變更狀態列"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"以狀態列顯示"</string>
@@ -1610,6 +1615,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量,比建議的音量更大聲嗎?\n\n長時間聆聽高分貝音量可能會使你的聽力受損。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙捷徑嗎?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"啟用捷徑功能後,只要同時按下兩個音量鍵 3 秒,就能啟動無障礙功能。\n\n 目前設定的無障礙功能為:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n 如要變更設定的功能,請依序輕觸 [設定] &gt; [無障礙設定]。"</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"空白"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"編輯捷徑"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"取消"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"停用捷徑"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用捷徑"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
@@ -1845,6 +1853,10 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"要開啟工作資料夾嗎?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"系統將開啟你的辦公應用程式、通知、資料和其他工作資料夾功能"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"開啟"</string>
+    <!-- no translation found for app_blocked_title (7353262160455028160) -->
+    <skip />
+    <!-- no translation found for app_blocked_message (542972921087873023) -->
+    <skip />
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"這個應用程式是專為舊版 Android 所打造,因此可能無法正常運作。請嘗試檢查更新,或是與開發人員聯絡。"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"你有新訊息"</string>
@@ -1955,13 +1967,14 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電池電力可能會在你平常的充電時間前耗盡"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已啟用節約耗電量模式以延長電池續航力"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"節約耗電量"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"電池電量不足時,節約耗電量模式才會再次開啟"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"電池電量已足夠。電池電量不足時,節約耗電量模式才會再次開啟。"</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"手機已充電至 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"平板電腦已充電至 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"裝置已充電至 <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"節約耗電量模式已關閉,各項功能不再受到限制。"</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"節約耗電量模式已關閉,各項功能不再受到限制。"</string>
+    <!-- no translation found for battery_saver_off_notification_title (7637255960468032515) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (5544457317418624367) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (4426317048139996888) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_summary (1031562417867646649) -->
+    <skip />
     <string name="mime_type_folder" msgid="2203536499348787650">"資料夾"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Android 應用程式"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"檔案"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ddaf38c..d736562 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -287,7 +287,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"finyelela kukhalenda yakho"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"I-SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"thumela uphinde ubuke imilayezo ye-SMS"</string>
-    <string name="permgrouplab_storage" msgid="1121695277384787841">"Isitoreji"</string>
+    <string name="permgrouplab_storage" msgid="1938416135375282333">"Amafayela nemidiya"</string>
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"finyelela kuzithombe, imidiya, namafayela kudivayisi yakho"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"I-Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"rekhoda ividiyo"</string>
@@ -313,6 +313,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Ingathepha, iswayiphe, incinze, futhi yenze okunye ukuthintwa."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Ukuthinta kwezigxivizo zeminwe"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Ingathatha ukuthinta okwenziwe kunzwa yezigxivizo zeminwe zedivayisi."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Thatha isithombe-skrini"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ingathatha isithombe-skrini sesiboniso"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"khubaza noma guqula ibha yomumo"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ivumela uhlelo lokusebenza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"yiba yibha yesimo"</string>
@@ -1610,6 +1612,9 @@
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Khuphukisa ivolumu ngaphezu kweleveli enconyiwe?\n\nUkulalela ngevolumu ephezulu izikhathi ezide kungahle kulimaze ukuzwa kwakho."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sebenzisa isinqamuleli sokufinyelela?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Uma kuvulwe isinqamuleli, ukucindezela zombili izinkinobho zevolumu amasekhondi angu-3 kuzoqala isici sokufinyelela.\n\n Isici samanje sokufinyelela:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Ungashintsha isici kuzilungiselelo &gt; Ukufinyelela."</string>
+    <string name="accessibility_shortcut_menu_button" msgid="3019329474891857428">"Akunalutho"</string>
+    <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Hlela izinqamuleli"</string>
+    <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Khansela"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vala isinqamuleli"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sebenzisa isinqamuleli"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Ukuguqulwa kombala"</string>
@@ -1845,6 +1850,8 @@
     <string name="work_mode_off_title" msgid="5503291976647976560">"Vula iphrofayela yomsebenzi?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"Izinhlelo zakho zokusebenza zomsebenzi, izaziso, idatha, nezinye izici zephrofayela yomsebenzi kuzovulwa"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Vula"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"Uhlelo lokusebenza alutholakali"</string>
+    <string name="app_blocked_message" msgid="542972921087873023">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayitholakali khona manje."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Lolu hlelo lokusebenza belakhelwe inguqulo endala ye-Android futhi kungenzeka lungasebenzi kahle. Zama ukuhlolela izibuyekezo, noma uxhumane nonjiniyela."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Hlola izibuyekezo"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Unemilayezo emisha"</string>
@@ -1955,13 +1962,10 @@
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Ibhethri lingaphela ngaphambi kokushaja okuvamile"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Isilondolozi sebhethri siyasebenza ngaphandle kwempilo yebhethri"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Isilondolozi sebhethri"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Isilondolozi sebhethri ngeke siphinde senziwe sisebenze lize libe phansi ibhethri futhi"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Ibhethri lishajwe kufikela kuleveli elanele. Isilondolozi sebhethri ngeke siphinde senziwe sisebenze ibhethri lize liphinde libe phansi futhi."</string>
-    <string name="battery_saver_charged_notification_title" product="default" msgid="3323003634503470433">"Ifoni engu-<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> igcwalisiwe"</string>
-    <string name="battery_saver_charged_notification_title" product="tablet" msgid="7917739170436791596">"Ithebulethi ishajwe ngokungu-<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_charged_notification_title" product="device" msgid="6316898726189914805">"Idivayisi ishajwe ngokungu-<xliff:g id="CHARGE_LEVEL">%1$s</xliff:g>"</string>
-    <string name="battery_saver_off_notification_summary" msgid="8489738830261291526">"Isilondolozi sebhethri sivaliwe. Izici azisakhawulelwe."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="8875240624827898671">"Isilondolozi sebhethri sivaliwe. Izici azisakhawulelwe."</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Isilondolozi sebhethri sivaliwe"</string>
+    <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Ifoni inokushajwa okwanele. Izici azisakhawulelwe."</string>
+    <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"Ithebulethi inokushajwa okwanele. Izici azisakhawulelwe."</string>
+    <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"Idivayisi inokushajwa okwanele. Izici azisakhawulelwe."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Ifolda"</string>
     <string name="mime_type_apk" msgid="3168784749499623902">"Uhlelo lokusebenza lwe-Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Ifayela"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4475415..e0d8492 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2217,6 +2217,16 @@
             Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER</code>.
             -->
             <enum name="never" value="2" />
+            <!-- <p>
+            The window is always allowed to extend into the <code>DisplayCutout</code> areas on the
+            all edges of the screen.
+            <p>
+            The window must make sure that no important content overlaps with the
+            <code>DisplayCutout</code>.
+            <p>
+            Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS</code>.
+            -->
+            <enum name="always" value="3" />
         </attr>
     </declare-styleable>
 
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 94f3b8a..0895edc 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1520,6 +1520,22 @@
         <!-- Managing a media projection session, e.g, for screen recording or taking
              screenshots.-->
         <flag name="mediaProjection" value="0x20" />
+        <!-- Use the camera device or record video.
+
+            <p>For apps with <code>targetSdkVersion</code> {@link android.os.Build.VERSION_CODES#R}
+            and above, a foreground service will not be able to access the camera if this type is
+            not specified in the manifest and in
+            {@link android.app.Service#startForeground(int, android.app.Notification, int)}.
+            -->
+        <flag name="camera" value="0x40" />
+        <!--Use the microphone device or record audio.
+
+            <p>For apps with <code>targetSdkVersion</code> {@link android.os.Build.VERSION_CODES#R}
+            and above, a foreground service will not be able to access the microphone if this type
+            is not specified in the manifest and in
+            {@link android.app.Service#startForeground(int, android.app.Notification, int)}.
+            -->
+        <flag name="microphone" value="0x80" />
     </attr>
 
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2585197..0c01e87 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -147,6 +147,24 @@
     <integer name="config_activityShortDur">150</integer>
     <integer name="config_activityDefaultDur">220</integer>
 
+    <!-- Fade out time for screen rotation -->
+    <integer name="config_screen_rotation_fade_out">116</integer>
+
+    <!-- Fade in time for screen rotation -->
+    <integer name="config_screen_rotation_fade_in">233</integer>
+
+    <!-- Fade in delay time for screen rotation -->
+    <integer name="config_screen_rotation_fade_in_delay">100</integer>
+
+    <!-- Total time for 90 degree screen rotation animations -->
+    <integer name="config_screen_rotation_total_90">333</integer>
+
+    <!-- Total time for 180 degree screen rotation animation -->
+    <integer name="config_screen_rotation_total_180">433</integer>
+
+    <!-- Total time for the rotation background color transition -->
+    <integer name="config_screen_rotation_color_transition">200</integer>
+
     <!-- The duration (in milliseconds) of the tooltip show/hide animations. -->
     <integer name="config_tooltipAnimTime">150</integer>
 
@@ -4303,4 +4321,19 @@
 
     <!-- Package name of the required service extension package. -->
     <string name="config_servicesExtensionPackage" translatable="false">android.ext.services</string>
+
+    <!-- Retention policy: number of records to kept for the historical exit info per package. -->
+    <integer name="config_app_exit_info_history_list_size">16</integer>
+
+    <!-- Packages that can't be killed even if it's requested to be killed on imperceptible -->
+    <string-array name="config_defaultImperceptibleKillingExemptionPkgs" translatable="false" />
+
+    <!-- Proc States that can't be killed even if it's requested to be killed on imperceptible -->
+    <integer-array name="config_defaultImperceptibleKillingExemptionProcStates">
+      <item>0</item> <!-- PROCESS_STATE_PERSISTENT -->
+      <item>1</item> <!-- PROCESS_STATE_PERSISTENT_UI -->
+      <item>2</item> <!-- PROCESS_STATE_TOP -->
+      <item>4</item> <!-- PROCESS_STATE_FOREGROUND_SERVICE -->
+      <item>12</item> <!-- PROCESS_STATE_TOP_SLEEPING -->
+    </integer-array>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a81565a..f25f97c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4359,10 +4359,8 @@
         You can change the feature in Settings > Accessibility.
     </string>
 
-    <!-- Text in button that edit the accessibility shortcut menu. [CHAR LIMIT=100] -->
-    <string name="accessibility_shortcut_menu_button">Empty</string>
-
-    <!-- Text in button that edit the accessibility shortcut menu. [CHAR LIMIT=100] -->
+    <!-- Text in button that edit the accessibility shortcut menu, user can delete
+    any service item in the menu list. [CHAR LIMIT=100] -->
     <string name="edit_accessibility_shortcut_menu_button">Edit shortcuts</string>
 
     <!-- Text in button that cancel the accessibility shortcut menu changed status. [CHAR LIMIT=100] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 379d0aa..28b0feac 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1805,7 +1805,6 @@
   <!-- From services -->
   <java-symbol type="anim" name="screen_rotate_0_enter" />
   <java-symbol type="anim" name="screen_rotate_0_exit" />
-  <java-symbol type="anim" name="screen_rotate_0_frame" />
   <java-symbol type="anim" name="screen_rotate_180_enter" />
   <java-symbol type="anim" name="screen_rotate_180_exit" />
   <java-symbol type="anim" name="screen_rotate_180_frame" />
@@ -1981,6 +1980,7 @@
   <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" />
   <java-symbol type="integer" name="config_brightness_ramp_rate_fast" />
   <java-symbol type="integer" name="config_brightness_ramp_rate_slow" />
+  <java-symbol type="integer" name="config_screen_rotation_color_transition" />
   <java-symbol type="layout" name="am_compat_mode_dialog" />
   <java-symbol type="layout" name="launch_warning" />
   <java-symbol type="layout" name="safe_mode" />
@@ -3820,4 +3820,10 @@
   <java-symbol type="string" name="capability_title_canTakeScreenshot" />
 
   <java-symbol type="string" name="config_servicesExtensionPackage" />
+
+  <!-- For app process exit info tracking -->
+  <java-symbol type="integer" name="config_app_exit_info_history_list_size" />
+
+  <java-symbol type="array" name="config_defaultImperceptibleKillingExemptionPkgs" />
+  <java-symbol type="array" name="config_defaultImperceptibleKillingExemptionProcStates" />
 </resources>
diff --git a/core/tests/coretests/res/values/styles.xml b/core/tests/coretests/res/values/styles.xml
index 0bf4b92..352b4dc 100644
--- a/core/tests/coretests/res/values/styles.xml
+++ b/core/tests/coretests/res/values/styles.xml
@@ -31,6 +31,9 @@
     <style name="LayoutInDisplayCutoutModeNever">
         <item name="android:windowLayoutInDisplayCutoutMode">never</item>
     </style>
+    <style name="LayoutInDisplayCutoutModeAlways">
+        <item name="android:windowLayoutInDisplayCutoutMode">always</item>
+    </style>
     <style name="WindowBackgroundColorLiteral">
         <item name="android:windowBackground">#00FF00</item>
     </style>
diff --git a/core/tests/coretests/src/android/accessibilityservice/AccessibilityServiceTest.java b/core/tests/coretests/src/android/accessibilityservice/AccessibilityServiceTest.java
new file mode 100644
index 0000000..c65ef9a
--- /dev/null
+++ b/core/tests/coretests/src/android/accessibilityservice/AccessibilityServiceTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.view.accessibility.AccessibilityEvent;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for AccessibilityService.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityServiceTest {
+    private static final String TAG = "AccessibilityServiceTest";
+    private static final int CONNECTION_ID = 1;
+
+    private static class AccessibilityServiceTestClass extends AccessibilityService {
+        private IAccessibilityServiceClient mCallback;
+        private Looper mLooper;
+
+        AccessibilityServiceTestClass() {
+            super();
+            attachBaseContext(InstrumentationRegistry.getContext());
+            mLooper = InstrumentationRegistry.getContext().getMainLooper();
+        }
+
+        public void setupCallback(IAccessibilityServiceClient callback) {
+            mCallback = callback;
+        }
+
+        public Looper getMainLooper() {
+            return mLooper;
+        }
+
+        public void onAccessibilityEvent(AccessibilityEvent event) { }
+        public void onInterrupt() { }
+
+        @Override
+        public void onSystemActionsChanged() {
+            try {
+                if (mCallback != null) mCallback.onSystemActionsChanged();
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    private @Mock IAccessibilityServiceClient  mMockClientForCallback;
+    private @Mock IAccessibilityServiceConnection mMockConnection;
+    private @Mock IBinder mMockIBinder;
+    private IAccessibilityServiceClient mServiceInterface;
+    private AccessibilityServiceTestClass mService;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+        mService = new AccessibilityServiceTestClass();
+        mService.setupCallback(mMockClientForCallback);
+        mServiceInterface = (IAccessibilityServiceClient) mService.onBind(new Intent());
+        mServiceInterface.init(mMockConnection, CONNECTION_ID, mMockIBinder);
+    }
+
+    @Test
+    public void testOnSystemActionsChanged() throws RemoteException {
+        mServiceInterface.onSystemActionsChanged();
+
+        verify(mMockClientForCallback).onSystemActionsChanged();
+    }
+
+    @Test
+    public void testGetSystemActions() throws RemoteException {
+        mService.getSystemActions();
+
+        verify(mMockConnection).getSystemActions();
+    }
+}
diff --git a/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java b/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
index abaeb0a..ae6d8df 100644
--- a/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
@@ -17,8 +17,10 @@
 package android.accessibilityservice;
 
 import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -48,6 +50,7 @@
 public class AccessibilityShortcutInfoTest {
     private Context mTargetContext;
     private PackageManager mPackageManager;
+    private ComponentName mComponentName;
     private AccessibilityShortcutInfo mShortcutInfo;
 
     @Before
@@ -55,25 +58,9 @@
         mTargetContext = InstrumentationRegistry.getInstrumentation()
                 .getTargetContext();
         mPackageManager = mTargetContext.getPackageManager();
-
-        final ComponentName testShortcutName = new ComponentName(mTargetContext,
-                AccessibilityTestActivity.class);
-        final AccessibilityManager accessibilityManager = (AccessibilityManager) mTargetContext
-                .getSystemService(Context.ACCESSIBILITY_SERVICE);
-        final List<AccessibilityShortcutInfo> infoList = accessibilityManager
-                .getInstalledAccessibilityShortcutListAsUser(
-                        mTargetContext, mTargetContext.getUserId());
-        for (AccessibilityShortcutInfo info : infoList) {
-            final ActivityInfo activityInfo = info.getActivityInfo();
-            final ComponentName name = new ComponentName(
-                    activityInfo.packageName, activityInfo.name);
-            if (name.equals(testShortcutName)) {
-                mShortcutInfo = info;
-                break;
-            }
-        }
-
-        assertNotNull("Can't find " + testShortcutName, mShortcutInfo);
+        mComponentName = new ComponentName(mTargetContext, AccessibilityTestActivity.class);
+        mShortcutInfo = getAccessibilityShortcutInfo(mComponentName);
+        assertNotNull("Can't find " + mComponentName, mShortcutInfo);
     }
 
     @Test
@@ -95,4 +82,38 @@
         assertThat("Summary is not correct",
                 mShortcutInfo.loadSummary(mPackageManager), is(summary));
     }
+
+    @Test
+    public void testEquals() {
+        assertTrue(mShortcutInfo.equals(mShortcutInfo));
+        assertFalse(mShortcutInfo.equals(null));
+        assertFalse(mShortcutInfo.equals(new Object()));
+
+        final AccessibilityShortcutInfo sameCopy = getAccessibilityShortcutInfo(
+                mComponentName);
+        assertTrue(mShortcutInfo != sameCopy);
+        assertTrue(mShortcutInfo.hashCode() == sameCopy.hashCode());
+        assertTrue(mShortcutInfo.getComponentName().equals(sameCopy.getComponentName()));
+        assertTrue(mShortcutInfo.equals(sameCopy));
+    }
+
+    @Test
+    public void testToString() {
+        assertNotNull(mShortcutInfo.toString());
+    }
+
+    private AccessibilityShortcutInfo getAccessibilityShortcutInfo(ComponentName componentName) {
+        final AccessibilityManager accessibilityManager = (AccessibilityManager) mTargetContext
+                .getSystemService(Context.ACCESSIBILITY_SERVICE);
+        final List<AccessibilityShortcutInfo> infoList = accessibilityManager
+                .getInstalledAccessibilityShortcutListAsUser(
+                        mTargetContext, mTargetContext.getUserId());
+        for (AccessibilityShortcutInfo info : infoList) {
+            final ActivityInfo activityInfo = info.getActivityInfo();
+            if (componentName.equals(activityInfo.getComponentName())) {
+                return info;
+            }
+        }
+        return null;
+    }
 }
diff --git a/core/tests/coretests/src/android/app/NotificationHistoryTest.java b/core/tests/coretests/src/android/app/NotificationHistoryTest.java
index f9a6a5c..0a21875 100644
--- a/core/tests/coretests/src/android/app/NotificationHistoryTest.java
+++ b/core/tests/coretests/src/android/app/NotificationHistoryTest.java
@@ -116,25 +116,28 @@
     @Test
     public void testAddNotificationsToWrite() {
         NotificationHistory history = new NotificationHistory();
-        HistoricalNotification n = getHistoricalNotification(0);
+        HistoricalNotification n = getHistoricalNotification(3);
         HistoricalNotification n2 = getHistoricalNotification(1);
+        HistoricalNotification n5 = getHistoricalNotification(0);
         history.addNotificationToWrite(n2);
         history.addNotificationToWrite(n);
+        history.addNotificationToWrite(n5);
 
         NotificationHistory secondHistory = new NotificationHistory();
-        HistoricalNotification n3 = getHistoricalNotification(2);
-        HistoricalNotification n4 = getHistoricalNotification(3);
+        HistoricalNotification n3 = getHistoricalNotification(4);
+        HistoricalNotification n4 = getHistoricalNotification(2);
         secondHistory.addNotificationToWrite(n4);
         secondHistory.addNotificationToWrite(n3);
 
         history.addNotificationsToWrite(secondHistory);
 
-        assertThat(history.getNotificationsToWrite().size()).isEqualTo(4);
-        assertThat(history.getNotificationsToWrite().get(0)).isSameAs(n2);
+        assertThat(history.getNotificationsToWrite().size()).isEqualTo(5);
+        assertThat(history.getNotificationsToWrite().get(0)).isSameAs(n3);
         assertThat(history.getNotificationsToWrite().get(1)).isSameAs(n);
         assertThat(history.getNotificationsToWrite().get(2)).isSameAs(n4);
-        assertThat(history.getNotificationsToWrite().get(3)).isSameAs(n3);
-        assertThat(history.getHistoryCount()).isEqualTo(4);
+        assertThat(history.getNotificationsToWrite().get(3)).isSameAs(n2);
+        assertThat(history.getNotificationsToWrite().get(4)).isSameAs(n5);
+        assertThat(history.getHistoryCount()).isEqualTo(5);
 
         assertThat(history.getPooledStringsToWrite()).asList().contains(n2.getChannelName());
         assertThat(history.getPooledStringsToWrite()).asList().contains(n4.getPackage());
diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java
index 2091d55..abba7fc 100644
--- a/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java
@@ -40,14 +40,14 @@
     @Test
     public void testDocumentEquals_Identical() {
         Document document1 = Document.newBuilder("uri1", "schemaType1")
-                .setCreationTimestampSecs(0L)
+                .setCreationTimestampMillis(5L)
                 .setProperty("longKey1", 1L, 2L, 3L)
                 .setProperty("doubleKey1", 1.0, 2.0, 3.0)
                 .setProperty("booleanKey1", true, false, true)
                 .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
                 .build();
         Document document2 = Document.newBuilder("uri1", "schemaType1")
-                .setCreationTimestampSecs(0L)
+                .setCreationTimestampMillis(5L)
                 .setProperty("longKey1", 1L, 2L, 3L)
                 .setProperty("doubleKey1", 1.0, 2.0, 3.0)
                 .setProperty("booleanKey1", true, false, true)
@@ -60,7 +60,7 @@
     @Test
     public void testDocumentEquals_DifferentOrder() {
         Document document1 = Document.newBuilder("uri1", "schemaType1")
-                .setCreationTimestampSecs(0L)
+                .setCreationTimestampMillis(5L)
                 .setProperty("longKey1", 1L, 2L, 3L)
                 .setProperty("doubleKey1", 1.0, 2.0, 3.0)
                 .setProperty("booleanKey1", true, false, true)
@@ -69,7 +69,7 @@
 
         // Create second document with same parameter but different order.
         Document document2 = Document.newBuilder("uri1", "schemaType1")
-                .setCreationTimestampSecs(0L)
+                .setCreationTimestampMillis(5L)
                 .setProperty("booleanKey1", true, false, true)
                 .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
                 .setProperty("doubleKey1", 1.0, 2.0, 3.0)
@@ -82,11 +82,13 @@
     @Test
     public void testDocumentEquals_Failure() {
         Document document1 = Document.newBuilder("uri1", "schemaType1")
+                .setCreationTimestampMillis(5L)
                 .setProperty("longKey1", 1L, 2L, 3L)
                 .build();
 
         // Create second document with same order but different value.
         Document document2 = Document.newBuilder("uri1", "schemaType1")
+                .setCreationTimestampMillis(5L)
                 .setProperty("longKey1", 1L, 2L, 4L) // Different
                 .build();
         assertThat(document1).isNotEqualTo(document2);
@@ -96,11 +98,13 @@
     @Test
     public void testDocumentEquals_Failure_RepeatedFieldOrder() {
         Document document1 = Document.newBuilder("uri1", "schemaType1")
+                .setCreationTimestampMillis(5L)
                 .setProperty("booleanKey1", true, false, true)
                 .build();
 
         // Create second document with same order but different value.
         Document document2 = Document.newBuilder("uri1", "schemaType1")
+                .setCreationTimestampMillis(5L)
                 .setProperty("booleanKey1", true, true, false) // Different
                 .build();
         assertThat(document1).isNotEqualTo(document2);
@@ -110,12 +114,16 @@
     @Test
     public void testDocumentGetSingleValue() {
         Document document = Document.newBuilder("uri1", "schemaType1")
+                .setCreationTimestampMillis(5L)
+                .setScore(1)
                 .setProperty("longKey1", 1L)
                 .setProperty("doubleKey1", 1.0)
                 .setProperty("booleanKey1", true)
                 .setProperty("stringKey1", "test-value1").build();
         assertThat(document.getUri()).isEqualTo("uri1");
         assertThat(document.getSchemaType()).isEqualTo("schemaType1");
+        assertThat(document.getCreationTimestampMillis()).isEqualTo(5);
+        assertThat(document.getScore()).isEqualTo(1);
         assertThat(document.getPropertyLong("longKey1")).isEqualTo(1L);
         assertThat(document.getPropertyDouble("doubleKey1")).isEqualTo(1.0);
         assertThat(document.getPropertyBoolean("booleanKey1")).isTrue();
@@ -125,7 +133,7 @@
     @Test
     public void testDocumentGetArrayValues() {
         Document document = Document.newBuilder("uri1", "schemaType1")
-                .setScore(1)
+                .setCreationTimestampMillis(5L)
                 .setProperty("longKey1", 1L, 2L, 3L)
                 .setProperty("doubleKey1", 1.0, 2.0, 3.0)
                 .setProperty("booleanKey1", true, false, true)
@@ -134,7 +142,6 @@
 
         assertThat(document.getUri()).isEqualTo("uri1");
         assertThat(document.getSchemaType()).isEqualTo("schemaType1");
-        assertThat(document.getScore()).isEqualTo(1);
         assertThat(document.getPropertyLongArray("longKey1")).asList().containsExactly(1L, 2L, 3L);
         assertThat(document.getPropertyDoubleArray("doubleKey1")).usingExactEquality()
                 .containsExactly(1.0, 2.0, 3.0);
@@ -181,8 +188,8 @@
     @Test
     public void testDocumentProtoPopulation() {
         Document document = Document.newBuilder("uri1", "schemaType1")
+                .setCreationTimestampMillis(5L)
                 .setScore(1)
-                .setCreationTimestampSecs(0)
                 .setProperty("longKey1", 1L)
                 .setProperty("doubleKey1", 1.0)
                 .setProperty("booleanKey1", true)
@@ -191,7 +198,7 @@
 
         // Create the Document proto. Need to sort the property order by key.
         DocumentProto.Builder documentProtoBuilder = DocumentProto.newBuilder()
-                .setUri("uri1").setSchema("schemaType1").setScore(1).setCreationTimestampSecs(0);
+                .setUri("uri1").setSchema("schemaType1").setScore(1).setCreationTimestampMs(5L);
         HashMap<String, PropertyProto.Builder> propertyProtoMap = new HashMap<>();
         propertyProtoMap.put("longKey1",
                 PropertyProto.newBuilder().setName("longKey1").addInt64Values(1L));
diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java
index 0be52c1..08ec2d0 100644
--- a/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java
@@ -21,14 +21,12 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
-import android.app.appsearch.AppSearchSchema.IndexingConfig;
 import android.app.appsearch.AppSearchSchema.PropertyConfig;
 
 import androidx.test.filters.SmallTest;
 
 import com.google.android.icing.proto.IndexingConfig.TokenizerType;
 import com.google.android.icing.proto.PropertyConfigProto;
-import com.google.android.icing.proto.SchemaProto;
 import com.google.android.icing.proto.SchemaTypeConfigProto;
 import com.google.android.icing.proto.TermMatchType;
 
@@ -37,94 +35,87 @@
 @SmallTest
 public class AppSearchSchemaTest {
     @Test
-    public void testSuccess() {
-        AppSearchSchema schema = AppSearchSchema.newBuilder()
-                .addType(AppSearchSchema.newSchemaTypeBuilder("Email")
-                        .addProperty(AppSearchSchema.newPropertyBuilder("subject")
-                                .setDataType(PropertyConfig.DATA_TYPE_STRING)
-                                .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                .setIndexingConfig(AppSearchSchema.newIndexingConfigBuilder()
-                                        .setTokenizerType(IndexingConfig.TOKENIZER_TYPE_PLAIN)
-                                        .setTermMatchType(IndexingConfig.TERM_MATCH_TYPE_PREFIX)
-                                        .build()
-                                ).build()
-                        ).addProperty(AppSearchSchema.newPropertyBuilder("body")
-                                .setDataType(PropertyConfig.DATA_TYPE_STRING)
-                                .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                .setIndexingConfig(AppSearchSchema.newIndexingConfigBuilder()
-                                        .setTokenizerType(IndexingConfig.TOKENIZER_TYPE_PLAIN)
-                                        .setTermMatchType(IndexingConfig.TERM_MATCH_TYPE_PREFIX)
-                                        .build()
-                                ).build()
-                        ).build()
-
-                ).addType(AppSearchSchema.newSchemaTypeBuilder("MusicRecording")
-                        .addProperty(AppSearchSchema.newPropertyBuilder("artist")
-                                .setDataType(PropertyConfig.DATA_TYPE_STRING)
-                                .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
-                                .setIndexingConfig(AppSearchSchema.newIndexingConfigBuilder()
-                                        .setTokenizerType(IndexingConfig.TOKENIZER_TYPE_PLAIN)
-                                        .setTermMatchType(IndexingConfig.TERM_MATCH_TYPE_PREFIX)
-                                        .build()
-                                ).build()
-                        ).addProperty(AppSearchSchema.newPropertyBuilder("pubDate")
-                                .setDataType(PropertyConfig.DATA_TYPE_INT64)
-                                .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                .setIndexingConfig(AppSearchSchema.newIndexingConfigBuilder()
-                                        .setTokenizerType(IndexingConfig.TOKENIZER_TYPE_NONE)
-                                        .setTermMatchType(IndexingConfig.TERM_MATCH_TYPE_UNKNOWN)
-                                        .build()
-                                ).build()
-                        ).build()
+    public void testGetProto_Email() {
+        AppSearchSchema emailSchema = AppSearchSchema.newBuilder("Email")
+                .addProperty(AppSearchSchema.newPropertyBuilder("subject")
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).addProperty(AppSearchSchema.newPropertyBuilder("body")
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
                 ).build();
 
-        SchemaProto expectedProto = SchemaProto.newBuilder()
-                .addTypes(SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType("Email")
-                        .addProperties(PropertyConfigProto.newBuilder()
-                                .setPropertyName("subject")
-                                .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                .setIndexingConfig(
-                                        com.google.android.icing.proto.IndexingConfig.newBuilder()
-                                                .setTokenizerType(TokenizerType.Code.PLAIN)
-                                                .setTermMatchType(TermMatchType.Code.PREFIX)
-                                )
-                        ).addProperties(PropertyConfigProto.newBuilder()
-                                .setPropertyName("body")
-                                .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                .setIndexingConfig(
-                                        com.google.android.icing.proto.IndexingConfig.newBuilder()
-                                                .setTokenizerType(TokenizerType.Code.PLAIN)
-                                                .setTermMatchType(TermMatchType.Code.PREFIX)
-                                )
+        SchemaTypeConfigProto expectedEmailProto = SchemaTypeConfigProto.newBuilder()
+                .setSchemaType("Email")
+                .addProperties(PropertyConfigProto.newBuilder()
+                        .setPropertyName("subject")
+                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
+                        .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
+                        .setIndexingConfig(
+                                com.google.android.icing.proto.IndexingConfig.newBuilder()
+                                        .setTokenizerType(TokenizerType.Code.PLAIN)
+                                        .setTermMatchType(TermMatchType.Code.PREFIX)
                         )
-
-                ).addTypes(SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType("MusicRecording")
-                        .addProperties(PropertyConfigProto.newBuilder()
-                                .setPropertyName("artist")
-                                .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                                .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
-                                .setIndexingConfig(
-                                        com.google.android.icing.proto.IndexingConfig.newBuilder()
-                                                .setTokenizerType(TokenizerType.Code.PLAIN)
-                                                .setTermMatchType(TermMatchType.Code.PREFIX)
-                                )
-                        ).addProperties(PropertyConfigProto.newBuilder()
-                                .setPropertyName("pubDate")
-                                .setDataType(PropertyConfigProto.DataType.Code.INT64)
-                                .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
-                                .setIndexingConfig(
-                                        com.google.android.icing.proto.IndexingConfig.newBuilder()
-                                                .setTokenizerType(TokenizerType.Code.NONE)
-                                                .setTermMatchType(TermMatchType.Code.UNKNOWN)
-                                )
+                ).addProperties(PropertyConfigProto.newBuilder()
+                        .setPropertyName("body")
+                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
+                        .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
+                        .setIndexingConfig(
+                                com.google.android.icing.proto.IndexingConfig.newBuilder()
+                                        .setTokenizerType(TokenizerType.Code.PLAIN)
+                                        .setTermMatchType(TermMatchType.Code.PREFIX)
                         )
                 ).build();
 
-        assertThat(schema.getProto()).isEqualTo(expectedProto);
+        assertThat(emailSchema.getProto()).isEqualTo(expectedEmailProto);
+    }
+
+    @Test
+    public void testGetProto_MusicRecording() {
+        AppSearchSchema musicRecordingSchema = AppSearchSchema.newBuilder("MusicRecording")
+                .addProperty(AppSearchSchema.newPropertyBuilder("artist")
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).addProperty(AppSearchSchema.newPropertyBuilder("pubDate")
+                        .setDataType(PropertyConfig.DATA_TYPE_INT64)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_NONE)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_NONE)
+                        .build()
+                ).build();
+
+        SchemaTypeConfigProto expectedMusicRecordingProto = SchemaTypeConfigProto.newBuilder()
+                .setSchemaType("MusicRecording")
+                .addProperties(PropertyConfigProto.newBuilder()
+                        .setPropertyName("artist")
+                        .setDataType(PropertyConfigProto.DataType.Code.STRING)
+                        .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
+                        .setIndexingConfig(
+                                com.google.android.icing.proto.IndexingConfig.newBuilder()
+                                        .setTokenizerType(TokenizerType.Code.PLAIN)
+                                        .setTermMatchType(TermMatchType.Code.PREFIX)
+                        )
+                ).addProperties(PropertyConfigProto.newBuilder()
+                        .setPropertyName("pubDate")
+                        .setDataType(PropertyConfigProto.DataType.Code.INT64)
+                        .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
+                        .setIndexingConfig(
+                                com.google.android.icing.proto.IndexingConfig.newBuilder()
+                                        .setTokenizerType(TokenizerType.Code.NONE)
+                                        .setTermMatchType(TermMatchType.Code.UNKNOWN)
+                        )
+                ).build();
+
+        assertThat(musicRecordingSchema.getProto()).isEqualTo(expectedMusicRecordingProto);
     }
 
     @Test
@@ -151,4 +142,25 @@
         builder.setCardinality(PropertyConfig.CARDINALITY_REPEATED);
         builder.build();
     }
+
+    @Test
+    public void testDuplicateProperties() {
+        AppSearchSchema.Builder builder = AppSearchSchema.newBuilder("Email")
+                .addProperty(AppSearchSchema.newPropertyBuilder("subject")
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).addProperty(AppSearchSchema.newPropertyBuilder("subject")
+                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                );
+
+        Exception e = expectThrows(IllegalSchemaException.class, builder::build);
+        assertThat(e).hasMessageThat().contains("Property defined more than once: subject");
+    }
 }
diff --git a/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java
index 4ee4aa6..c5986bb 100644
--- a/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java
@@ -36,7 +36,7 @@
     public void testBuildCustomerDocument() {
         CustomerDocument customerDocument = CustomerDocument.newBuilder("uri1")
                 .setScore(1)
-                .setCreationTimestampSecs(0)
+                .setCreationTimestampMillis(0)
                 .setProperty("longKey1", 1L, 2L, 3L)
                 .setProperty("doubleKey1", 1.0, 2.0, 3.0)
                 .setProperty("booleanKey1", true, false, true)
@@ -46,7 +46,7 @@
         assertThat(customerDocument.getUri()).isEqualTo("uri1");
         assertThat(customerDocument.getSchemaType()).isEqualTo("customerDocument");
         assertThat(customerDocument.getScore()).isEqualTo(1);
-        assertThat(customerDocument.getCreationTimestampSecs()).isEqualTo(0L);
+        assertThat(customerDocument.getCreationTimestampMillis()).isEqualTo(0L);
         assertThat(customerDocument.getPropertyLongArray("longKey1")).asList()
                 .containsExactly(1L, 2L, 3L);
         assertThat(customerDocument.getPropertyDoubleArray("doubleKey1")).usingExactEquality()
diff --git a/core/tests/coretests/src/android/content/PermissionCheckerTest.java b/core/tests/coretests/src/android/content/PermissionCheckerTest.java
new file mode 100644
index 0000000..cb04a74
--- /dev/null
+++ b/core/tests/coretests/src/android/content/PermissionCheckerTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.AppOpsManager;
+import android.app.UiAutomation;
+import android.os.Binder;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+// TODO(b/147877945): Add missing tests.
+@RunWith(AndroidJUnit4.class)
+public class PermissionCheckerTest {
+    private static final String INTERACT_ACROSS_PROFILES_PERMISSION =
+            "android.permission.INTERACT_ACROSS_PROFILES";
+    private static final String MANAGE_APP_OPS_MODE = "android.permission.MANAGE_APP_OPS_MODES";
+
+    private  final Context mContext = InstrumentationRegistry.getContext();;
+    private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+    private UiAutomation mUiAutomation =
+            InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+    @After
+    public void tearDown() {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    @Test
+    public void testCheckPermissionForPreflight_appOpPermission_modeDefaultAndPermissionGranted_returnsGranted() {
+        mUiAutomation.adoptShellPermissionIdentity(
+                INTERACT_ACROSS_PROFILES_PERMISSION, MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_DEFAULT);
+
+        assertThat(PermissionChecker.checkPermissionForPreflight(
+                    mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                    Binder.getCallingUid(), mContext.getPackageName()))
+                .isEqualTo(PermissionChecker.PERMISSION_GRANTED);
+    }
+
+    @Test
+    public void testCheckPermissionForPreflight_appOpPermission_modeDefaultAndPermissionNotGranted_returnsHardDenied() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_DEFAULT);
+
+        assertThat(PermissionChecker.checkPermissionForPreflight(
+                    mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                    Binder.getCallingUid(), mContext.getPackageName()))
+                .isEqualTo(PermissionChecker.PERMISSION_HARD_DENIED);
+    }
+
+    @Test
+    public void testCheckPermissionForPreflight_appOpPermission_modeAllowed_returnsGranted() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_ALLOWED);
+
+        assertThat(PermissionChecker.checkPermissionForPreflight(
+                    mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                    Binder.getCallingUid(), mContext.getPackageName()))
+                .isEqualTo(PermissionChecker.PERMISSION_GRANTED);
+    }
+
+    @Test
+    public void testCheckPermissionForPreflight_appOpPermission_packageNameIsNull_returnsGranted() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_ALLOWED);
+
+        assertThat(PermissionChecker.checkPermissionForPreflight(
+                    mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                    Binder.getCallingUid(), /* packageName= */ null))
+                .isEqualTo(PermissionChecker.PERMISSION_GRANTED);
+    }
+
+    @Test
+    public void testCheckPermissionForPreflight_appOpPermission_modeIgnored_returnsHardDenied() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_IGNORED);
+
+        assertThat(PermissionChecker.checkPermissionForPreflight(
+                    mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                    Binder.getCallingUid(), mContext.getPackageName()))
+                .isEqualTo(PermissionChecker.PERMISSION_HARD_DENIED);
+    }
+
+    @Test
+    public void testCheckPermissionForPreflight_appOpPermission_modeErrored_returnsHardDenied() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_ERRORED);
+
+        assertThat(PermissionChecker.checkPermissionForPreflight(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), mContext.getPackageName()))
+                .isEqualTo(PermissionChecker.PERMISSION_HARD_DENIED);
+    }
+
+    @Test
+    public void testCheckPermissionForDataDelivery_appOpPermission_modeDefaultAndPermissionGranted_returnsGranted() {
+        mUiAutomation.adoptShellPermissionIdentity(
+                INTERACT_ACROSS_PROFILES_PERMISSION, MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_DEFAULT);
+
+        assertThat(PermissionChecker.checkPermissionForDataDelivery(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), mContext.getPackageName(), /* featureId= */null,
+                /* message= */null)).isEqualTo(PermissionChecker.PERMISSION_GRANTED);
+    }
+
+    @Test
+    public void testCheckPermissionForDataDelivery_appOpPermission_modeDefaultAndPermissionNotGranted_returnsHardDenied() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_DEFAULT);
+
+        assertThat(PermissionChecker.checkPermissionForDataDelivery(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), mContext.getPackageName(), /* featureId= */null,
+                /* message= */null)).isEqualTo(PermissionChecker.PERMISSION_HARD_DENIED);
+    }
+
+    @Test
+    public void testCheckPermissionForDataDelivery_appOpPermission_modeAllowed_returnsGranted() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_ALLOWED);
+
+        assertThat(PermissionChecker.checkPermissionForDataDelivery(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), mContext.getPackageName(), /* featureId= */null,
+                /* message= */null)).isEqualTo(PermissionChecker.PERMISSION_GRANTED);
+    }
+
+    @Test
+    public void testCheckPermissionForDataDelivery_appOpPermission_packageNameIsNull_returnsGranted() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_ALLOWED);
+
+        assertThat(PermissionChecker.checkPermissionForDataDelivery(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), /* packageName= */ null, /* featureId= */null,
+                /* message= */null)).isEqualTo(PermissionChecker.PERMISSION_GRANTED);
+    }
+
+    @Test
+    public void testCheckPermissionForDataDelivery_appOpPermission_modeIgnored_returnsHardDenied() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_IGNORED);
+
+        assertThat(PermissionChecker.checkPermissionForDataDelivery(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), mContext.getPackageName(), /* featureId= */null,
+                /* message= */null)).isEqualTo(PermissionChecker.PERMISSION_HARD_DENIED);
+    }
+
+    @Test
+    public void testCheckPermissionForDataDelivery_appOpPermission_modeErrored_returnsHardDenied() {
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_APP_OPS_MODE);
+        mAppOpsManager.setMode(AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION),
+                Binder.getCallingUid(), mContext.getPackageName(), AppOpsManager.MODE_ERRORED);
+
+        assertThat(PermissionChecker.checkPermissionForDataDelivery(
+                mContext, INTERACT_ACROSS_PROFILES_PERMISSION, Binder.getCallingPid(),
+                Binder.getCallingUid(), mContext.getPackageName(), /* featureId= */null,
+                /* message= */null)).isEqualTo(PermissionChecker.PERMISSION_HARD_DENIED);
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
index dfd762b..47c4286 100644
--- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -470,7 +470,7 @@
         PackageParser.collectCertificates(p, false);
         PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags);
 
-        assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
+        assertEquals("com.google.android.tzdata2", pi.applicationInfo.packageName);
         assertTrue(pi.applicationInfo.enabled);
         assertEquals(28, pi.applicationInfo.targetSdkVersion);
         assertEquals(191000070, pi.applicationInfo.longVersionCode);
@@ -479,7 +479,7 @@
         assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]",
                 pi.applicationInfo.metaData.toString());
 
-        assertEquals("com.google.android.tzdata", pi.packageName);
+        assertEquals("com.google.android.tzdata2", pi.packageName);
         assertEquals(191000070, pi.getLongVersionCode());
         assertNotNull(pi.signingInfo);
         assertTrue(pi.signingInfo.getApkContentsSigners().length > 0);
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index d5a0dfa..7c2b98f 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -69,6 +69,8 @@
             null /* boundBottom */);
 
     final DisplayCutout mCutoutTop = createCutoutTop();
+    final DisplayCutout mCutoutWithWaterfall = createCutoutWithWaterfall();
+    final DisplayCutout mWaterfallOnly = createCutoutWaterfallOnly();
 
     @Test
     public void testExtractBoundsFromList_left() {
@@ -126,9 +128,23 @@
     }
 
     @Test
-    public void hasCutout() throws Exception {
-        assertTrue(NO_CUTOUT.isEmpty());
-        assertFalse(mCutoutTop.isEmpty());
+    public void testHasCutout_noCutout() throws Exception {
+        assertTrue(NO_CUTOUT.isBoundsEmpty());
+    }
+
+    @Test
+    public void testHasCutout_cutoutOnly() {
+        assertFalse(mCutoutTop.isBoundsEmpty());
+    }
+
+    @Test
+    public void testHasCutout_cutoutWithWaterfall() {
+        assertFalse(mCutoutWithWaterfall.isBoundsEmpty());
+    }
+
+    @Test
+    public void testHasCutout_waterfallOnly() {
+        assertTrue(mWaterfallOnly.isBoundsEmpty());
     }
 
     @Test
@@ -142,20 +158,27 @@
     }
 
     @Test
+    public void testGetWaterfallInsets() throws Exception {
+        DisplayCutout cutout =
+                createCutoutWaterfallOnly(Insets.of(5, 6, 7, 8));
+        assertEquals(Insets.of(5, 6, 7, 8), cutout.getWaterfallInsets());
+    }
+
+    @Test
     public void testHashCode() throws Exception {
-        assertEquals(mCutoutTop.hashCode(), createCutoutTop().hashCode());
-        assertNotEquals(mCutoutTop.hashCode(), mCutoutNumbers.hashCode());
+        assertEquals(mCutoutWithWaterfall.hashCode(), createCutoutWithWaterfall().hashCode());
+        assertNotEquals(mCutoutWithWaterfall.hashCode(), mCutoutNumbers.hashCode());
     }
 
     @Test
     public void testEquals() throws Exception {
-        assertEquals(mCutoutTop, createCutoutTop());
-        assertNotEquals(mCutoutTop, mCutoutNumbers);
+        assertEquals(mCutoutWithWaterfall, createCutoutWithWaterfall());
+        assertNotEquals(mCutoutWithWaterfall, mCutoutNumbers);
     }
 
     @Test
     public void testToString() throws Exception {
-        assertFalse(mCutoutTop.toString().isEmpty());
+        assertFalse(mCutoutWithWaterfall.toString().isEmpty());
         assertFalse(mCutoutNumbers.toString().isEmpty());
     }
 
@@ -240,12 +263,12 @@
     public void parcel_unparcel_regular() {
         Parcel p = Parcel.obtain();
 
-        new ParcelableWrapper(mCutoutTop).writeToParcel(p, 0);
+        new ParcelableWrapper(mCutoutWithWaterfall).writeToParcel(p, 0);
         int posAfterWrite = p.dataPosition();
 
         p.setDataPosition(0);
 
-        assertEquals(mCutoutTop, ParcelableWrapper.CREATOR.createFromParcel(p).get());
+        assertEquals(mCutoutWithWaterfall, ParcelableWrapper.CREATOR.createFromParcel(p).get());
         assertEquals(posAfterWrite, p.dataPosition());
     }
 
@@ -264,44 +287,64 @@
 
     @Test
     public void fromSpec_caches() {
-        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f);
-        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), sameInstance(cached));
+        Insets waterfallInsets = Insets.of(0, 20, 0, 20);
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f, waterfallInsets);
+        assertThat(
+                fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f, waterfallInsets),
+                sameInstance(cached));
     }
 
     @Test
     public void fromSpec_wontCacheIfSpecChanges() {
-        DisplayCutout cached = fromSpec("L1,0 L1000,1000 L0,1 z", 200, 400, 1f);
-        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
+        DisplayCutout cached = fromSpec("L1,0 L1000,1000 L0,1 z", 200, 400, 1f, Insets.NONE);
+        assertThat(
+                fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f, Insets.NONE),
+                not(sameInstance(cached)));
     }
 
     @Test
     public void fromSpec_wontCacheIfScreenWidthChanges() {
-        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 2000, 400, 1f);
-        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 2000, 400, 1f, Insets.NONE);
+        assertThat(
+                fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f, Insets.NONE),
+                not(sameInstance(cached)));
     }
 
     @Test
     public void fromSpec_wontCacheIfScreenHeightChanges() {
-        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 4000, 1f);
-        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 4000, 1f, Insets.NONE);
+        assertThat(
+                fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f, Insets.NONE),
+                not(sameInstance(cached)));
     }
 
     @Test
     public void fromSpec_wontCacheIfDensityChanges() {
-        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 2f);
-        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 2f, Insets.NONE);
+        assertThat(
+                fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f, Insets.NONE),
+                not(sameInstance(cached)));
+    }
+
+    @Test
+    public void fromSpec_wontCacheIfWaterfallInsetsChange() {
+        Insets waterfallInsets = Insets.of(0, 20, 0, 20);
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 2f, Insets.NONE);
+        assertThat(
+                fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 2f, waterfallInsets),
+                not(sameInstance(cached)));
     }
 
     @Test
     public void fromSpec_setsSafeInsets_top() {
-        DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z", 200, 400, 2f);
+        DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z", 200, 400, 2f, Insets.NONE);
         assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 0)));
     }
 
     @Test
     public void fromSpec_setsSafeInsets_top_and_bottom() {
         DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z"
-                + "@bottom M -50,0 v -10,0 h 100 v 20 z", 200, 400, 2f);
+                + "@bottom M -50,0 v -10,0 h 100 v 20 z", 200, 400, 2f, Insets.NONE);
         assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 10)));
         assertThat(cutout.getBoundingRectsAll(), equalTo(new Rect[]{
                 ZERO_RECT, new Rect(50, 0, 150, 20),
@@ -310,6 +353,38 @@
     }
 
     @Test
+    public void fromSpec_setsSafeInsets_waterfallTopBottom() {
+        DisplayCutout cutout = fromSpec("", 200, 400, 2f, Insets.of(0, 30, 0, 30));
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 30, 0, 30)));
+    }
+
+    @Test
+    public void fromSpec_setsSafeInsets_waterfallLeftRight() {
+        DisplayCutout cutout = fromSpec("", 200, 400, 2f, Insets.of(30, 0, 30, 0));
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(30, 0, 30, 0)));
+    }
+
+    @Test
+    public void fromSpec_setsSafeInsets_waterfall_allEdges() {
+        DisplayCutout cutout = fromSpec("", 200, 400, 2f, Insets.of(30, 30, 30, 30));
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(30, 30, 30, 30)));
+    }
+
+    @Test
+    public void fromSpec_setsSafeInsets_cutoutTopBottom_waterfallTopBottom() {
+        DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z"
+                + "@bottom M -50,0 v -20,0 h 100 v 20 z", 200, 400, 2f, Insets.of(0, 30, 0, 30));
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 30, 0, 30)));
+    }
+
+    @Test
+    public void fromSpec_setsSafeInsets_cutoutTopBottom_waterfallLeftRight() {
+        DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z"
+                + "@bottom M -50,0 v -20,0 h 100 v 20 z", 200, 400, 2f, Insets.of(30, 0, 30, 0));
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(30, 20, 30, 20)));
+    }
+
+    @Test
     public void parcel_unparcel_nocutout() {
         Parcel p = Parcel.obtain();
 
@@ -326,7 +401,7 @@
     public void parcel_unparcel_inplace() {
         Parcel p = Parcel.obtain();
 
-        new ParcelableWrapper(mCutoutTop).writeToParcel(p, 0);
+        new ParcelableWrapper(mCutoutWithWaterfall).writeToParcel(p, 0);
         int posAfterWrite = p.dataPosition();
 
         p.setDataPosition(0);
@@ -334,22 +409,24 @@
         ParcelableWrapper wrapper = new ParcelableWrapper();
         wrapper.readFromParcel(p);
 
-        assertEquals(mCutoutTop, wrapper.get());
+        assertEquals(mCutoutWithWaterfall, wrapper.get());
         assertEquals(posAfterWrite, p.dataPosition());
     }
 
     @Test
     public void wrapper_hashcode() throws Exception {
-        assertEquals(new ParcelableWrapper(mCutoutTop).hashCode(),
-                new ParcelableWrapper(createCutoutTop()).hashCode());
-        assertNotEquals(new ParcelableWrapper(mCutoutTop).hashCode(),
+        assertEquals(new ParcelableWrapper(mCutoutWithWaterfall).hashCode(),
+                new ParcelableWrapper(createCutoutWithWaterfall()).hashCode());
+        assertNotEquals(new ParcelableWrapper(mCutoutWithWaterfall).hashCode(),
                 new ParcelableWrapper(mCutoutNumbers).hashCode());
     }
 
     @Test
     public void wrapper_equals() throws Exception {
-        assertEquals(new ParcelableWrapper(mCutoutTop), new ParcelableWrapper(createCutoutTop()));
-        assertNotEquals(new ParcelableWrapper(mCutoutTop), new ParcelableWrapper(mCutoutNumbers));
+        assertEquals(new ParcelableWrapper(mCutoutWithWaterfall),
+                new ParcelableWrapper(createCutoutWithWaterfall()));
+        assertNotEquals(new ParcelableWrapper(mCutoutWithWaterfall),
+                new ParcelableWrapper(mCutoutNumbers));
     }
 
     private static DisplayCutout createCutoutTop() {
@@ -363,4 +440,28 @@
                 safeInset, null /* boundLeft */, boundTop, null /* boundRight */,
                 null /* boundBottom */);
     }
+
+    private static DisplayCutout createCutoutWithWaterfall() {
+        return new DisplayCutout(
+                Insets.of(20, 100, 20, 0),
+                ZERO_RECT,
+                new Rect(50, 0, 75, 100),
+                ZERO_RECT,
+                ZERO_RECT,
+                Insets.of(20, 0, 20, 0));
+    }
+
+    private static DisplayCutout createCutoutWaterfallOnly() {
+        return createCutoutWaterfallOnly(Insets.of(20, 0, 20, 0));
+    }
+
+    private static DisplayCutout createCutoutWaterfallOnly(Insets waterfallInsets) {
+        return new DisplayCutout(
+                Insets.of(20, 0, 20, 0),
+                ZERO_RECT,
+                ZERO_RECT,
+                ZERO_RECT,
+                ZERO_RECT,
+                waterfallInsets);
+    }
 }
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index d0fd92a..7c78bce 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -74,7 +74,7 @@
                     false,
                     new DisplayCutout(
                             Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
-                    rect, rect, SOFT_INPUT_ADJUST_RESIZE);
+                    rect, rect, SOFT_INPUT_ADJUST_RESIZE, 0);
             mImeConsumer = new ImeInsetsSourceConsumer(
                     new InsetsState(), Transaction::new, mController);
         });
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index fa61a0a..f2852fa 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -21,10 +21,14 @@
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowInsets.Type.systemBars;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -39,6 +43,8 @@
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import android.view.test.InsetsModeSession;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -50,8 +56,6 @@
 
 import java.util.List;
 
-import androidx.test.runner.AndroidJUnit4;
-
 /**
  * Tests for {@link InsetsAnimationControlImpl}.
  *
@@ -90,6 +94,8 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        doNothing().when(mMockController).updateCompatSysUiVisibility(
+                anyInt(), anyBoolean(), anyBoolean());
         mTopLeash = new SurfaceControl.Builder(mSession)
                 .setName("testSurface")
                 .build();
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 628f7ec..8381903 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -114,7 +114,7 @@
                     false,
                     new DisplayCutout(
                             Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
-                    rect, rect, SOFT_INPUT_ADJUST_RESIZE);
+                    rect, rect, SOFT_INPUT_ADJUST_RESIZE, 0);
             mController.onFrameChanged(new Rect(0, 0, 100, 100));
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index 4b76fee..9e4b1c5 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -23,6 +23,7 @@
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
@@ -72,7 +73,7 @@
             mState.getSource(ITYPE_IME).setVisible(true);
             SparseIntArray typeSideMap = new SparseIntArray();
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
-                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, typeSideMap);
+                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, typeSideMap);
             assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets());
             assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all()));
             assertEquals(ISIDE_TOP, typeSideMap.get(ITYPE_STATUS_BAR));
@@ -91,7 +92,7 @@
             mState.getSource(ITYPE_IME).setFrame(new Rect(0, 100, 100, 300));
             mState.getSource(ITYPE_IME).setVisible(true);
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
-                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, null);
+                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, null);
             assertEquals(100, insets.getStableInsetBottom());
             assertEquals(Insets.of(0, 0, 0, 100), insets.getMaxInsets(Type.systemBars()));
             assertEquals(Insets.of(0, 0, 0, 200), insets.getSystemWindowInsets());
@@ -110,7 +111,7 @@
             mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
             mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
-                    DisplayCutout.NO_CUTOUT, null, null, 0, null);
+                    DisplayCutout.NO_CUTOUT, null, null, 0, 0, null);
             assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
             assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
             assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
@@ -126,7 +127,7 @@
             mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
             mState.getSource(ITYPE_IME).setVisible(true);
             WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
-                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING, null);
+                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING, 0, null);
             assertEquals(0, insets.getSystemWindowInsetBottom());
             assertEquals(100, insets.getInsets(ime()).bottom);
             assertTrue(insets.isVisible(ime()));
@@ -134,6 +135,25 @@
     }
 
     @Test
+    public void testCalculateInsets_systemUiFlagLayoutStable() {
+        try (final InsetsModeSession session =
+                     new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) {
+            mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+            mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
+            mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
+            mState.getSource(ITYPE_IME).setVisible(true);
+            WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
+                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING,
+                    SYSTEM_UI_FLAG_LAYOUT_STABLE, null);
+            assertEquals(100, insets.getSystemWindowInsetTop());
+            insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
+                    DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_NOTHING,
+                    0 /* legacySystemUiFlags */, null);
+            assertEquals(0, insets.getSystemWindowInsetTop());
+        }
+    }
+
+    @Test
     public void testStripForDispatch() {
         mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
         mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
@@ -141,7 +161,7 @@
         mState.getSource(ITYPE_IME).setVisible(true);
         mState.removeSource(ITYPE_IME);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), false, false,
-                DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, null);
+                DisplayCutout.NO_CUTOUT, null, null, SOFT_INPUT_ADJUST_RESIZE, 0, null);
         assertEquals(0, insets.getSystemWindowInsetBottom());
     }
 
diff --git a/core/tests/coretests/src/android/view/WindowInsetsTest.java b/core/tests/coretests/src/android/view/WindowInsetsTest.java
index e5a4f6d..fce2ebd 100644
--- a/core/tests/coretests/src/android/view/WindowInsetsTest.java
+++ b/core/tests/coretests/src/android/view/WindowInsetsTest.java
@@ -16,10 +16,12 @@
 
 package android.view;
 
+import static android.view.WindowInsets.Type.SIZE;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 
+import static android.view.WindowInsets.Type.systemBars;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -28,6 +30,7 @@
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowInsets.Builder;
+import android.view.WindowInsets.Type;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -56,6 +59,18 @@
         assertTrue(new WindowInsets((Rect) null).isConsumed());
     }
 
+    @Test
+    public void compatInsets_layoutStable() {
+        Insets[] insets = new Insets[SIZE];
+        Insets[] maxInsets = new Insets[SIZE];
+        boolean[] visible = new boolean[SIZE];
+        WindowInsets.assignCompatInsets(maxInsets, new Rect(0, 10, 0, 0));
+        WindowInsets.assignCompatInsets(insets, new Rect(0, 0, 0, 0));
+        WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, false, null,
+                systemBars(), true /* compatIgnoreVisibility */);
+        assertEquals(Insets.of(0, 10, 0, 0), windowInsets.getSystemWindowInsets());
+    }
+
     // TODO: Move this to CTS once API made public
     @Test
     public void typeMap() {
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index f151b81..8b8e9ea 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -25,6 +25,9 @@
 import android.os.IBinder;
 import android.os.RemoteCallback;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Stub implementation of IAccessibilityServiceConnection so each test doesn't need to implement
  * all of the methods
@@ -85,6 +88,10 @@
         return false;
     }
 
+    public List<AccessibilityNodeInfo.AccessibilityAction> getSystemActions() {
+        return Collections.emptyList();
+    }
+
     public void disableSelf() {}
 
     public void setOnKeyEventResult(boolean handled, int sequence) {}
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
index 6c2d630..916e2b5 100644
--- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.policy;
 
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
@@ -94,6 +95,15 @@
     }
 
     @Test
+    public void layoutInDisplayCutoutMode_always() throws Exception {
+        createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeAlways);
+        installDecor();
+
+        assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
+                is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS));
+    }
+
+    @Test
     public void testWindowBackground_colorLiteral() {
         createPhoneWindowWithTheme(R.style.WindowBackgroundColorLiteral);
         installDecor();
diff --git a/core/tests/overlaytests/host/Android.bp b/core/tests/overlaytests/host/Android.bp
new file mode 100644
index 0000000..a2fcef5
--- /dev/null
+++ b/core/tests/overlaytests/host/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+java_test_host {
+    name: "OverlayHostTests",
+    srcs: ["src/**/*.java"],
+    libs: ["tradefed"],
+    test_suites: ["general-tests"],
+    target_required: [
+        "OverlayHostTests_NonPlatformSignatureOverlay",
+        "OverlayHostTests_PlatformSignatureStaticOverlay",
+        "OverlayHostTests_PlatformSignatureOverlay",
+        "OverlayHostTests_UpdateOverlay",
+        "OverlayHostTests_FrameworkOverlayV1",
+        "OverlayHostTests_FrameworkOverlayV2",
+        "OverlayHostTests_AppOverlayV1",
+        "OverlayHostTests_AppOverlayV2",
+    ],
+}
diff --git a/core/tests/overlaytests/host/Android.mk b/core/tests/overlaytests/host/Android.mk
index e7348d5..d58d939 100644
--- a/core/tests/overlaytests/host/Android.mk
+++ b/core/tests/overlaytests/host/Android.mk
@@ -14,23 +14,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE := OverlayHostTests
-LOCAL_JAVA_LIBRARIES := tradefed
-LOCAL_COMPATIBILITY_SUITE := general-tests
-LOCAL_TARGET_REQUIRED_MODULES := \
-    OverlayHostTests_NonPlatformSignatureOverlay \
-    OverlayHostTests_PlatformSignatureStaticOverlay \
-    OverlayHostTests_PlatformSignatureOverlay \
-    OverlayHostTests_UpdateOverlay \
-    OverlayHostTests_FrameworkOverlayV1 \
-    OverlayHostTests_FrameworkOverlayV2 \
-    OverlayHostTests_AppOverlayV1 \
-    OverlayHostTests_AppOverlayV2
-include $(BUILD_HOST_JAVA_LIBRARY)
-
 # Include to build test-apps.
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index ad99ab3..18b5f5d 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -68,7 +68,6 @@
     <privapp-permissions package="com.android.managedprovisioning">
         <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
         <permission name="android.permission.CHANGE_CONFIGURATION"/>
-        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
         <permission name="android.permission.CRYPT_KEEPER"/>
         <permission name="android.permission.DELETE_PACKAGES"/>
         <permission name="android.permission.INSTALL_PACKAGES"/>
@@ -153,6 +152,7 @@
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
         <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.READ_CARRIER_APP_INFO"/>
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
@@ -311,6 +311,7 @@
         <!-- Needed for test only -->
         <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
         <permission name="android.permission.POWER_SAVER" />
+        <permission name="android.permission.READ_CARRIER_APP_INFO"/>
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
         <!-- Needed for test only -->
@@ -373,7 +374,6 @@
     </privapp-permissions>
 
     <privapp-permissions package="com.android.vpndialogs">
-        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
         <permission name="android.permission.CONTROL_VPN"/>
     </privapp-permissions>
 
diff --git a/identity/MODULE_LICENSE_APACHE2 b/identity/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/identity/MODULE_LICENSE_APACHE2
diff --git a/identity/NOTICE b/identity/NOTICE
new file mode 100644
index 0000000..64aaa8d
--- /dev/null
+++ b/identity/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2009, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/identity/OWNERS b/identity/OWNERS
new file mode 100644
index 0000000..533d90b
--- /dev/null
+++ b/identity/OWNERS
@@ -0,0 +1,3 @@
+swillden@google.com
+zeuthen@google.com
+
diff --git a/identity/java/android/security/identity/AccessControlProfile.java b/identity/java/android/security/identity/AccessControlProfile.java
new file mode 100644
index 0000000..10e451c
--- /dev/null
+++ b/identity/java/android/security/identity/AccessControlProfile.java
@@ -0,0 +1,131 @@
+/*
+ * 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.security.identity;
+
+import android.annotation.NonNull;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * A class used to specify access controls.
+ */
+public class AccessControlProfile {
+    private AccessControlProfileId mAccessControlProfileId = new AccessControlProfileId(0);
+    private X509Certificate mReaderCertificate = null;
+    private boolean mUserAuthenticationRequired = true;
+    private long mUserAuthenticationTimeout = 0;
+
+    private AccessControlProfile() {
+    }
+
+    AccessControlProfileId getAccessControlProfileId() {
+        return mAccessControlProfileId;
+    }
+
+    long getUserAuthenticationTimeout() {
+        return mUserAuthenticationTimeout;
+    }
+
+    boolean isUserAuthenticationRequired() {
+        return mUserAuthenticationRequired;
+    }
+
+    X509Certificate getReaderCertificate() {
+        return mReaderCertificate;
+    }
+
+    /**
+     * A builder for {@link AccessControlProfile}.
+     */
+    public static final class Builder {
+        private AccessControlProfile mProfile;
+
+        /**
+         * Each access control profile has numeric identifier that must be unique within the
+         * context of a Credential and may be used to reference the profile.
+         *
+         * <p>By default, the resulting {@link AccessControlProfile} will require user
+         * authentication with a timeout of zero, thus requiring the holder to authenticate for
+         * every presentation where data elements using this access control profile is used.</p>
+         *
+         * @param accessControlProfileId the access control profile identifier.
+         */
+        public Builder(@NonNull AccessControlProfileId accessControlProfileId) {
+            mProfile = new AccessControlProfile();
+            mProfile.mAccessControlProfileId = accessControlProfileId;
+        }
+
+        /**
+         * Set whether user authentication is required.
+         *
+         * <p>This should be used sparingly since disabling user authentication on just a single
+         * data element can easily create a
+         * <a href="https://en.wikipedia.org/wiki/Relay_attack">Relay Attack</a> if the device
+         * on which the credential is stored is compromised.</p>
+         *
+         * @param userAuthenticationRequired Set to true if user authentication is required,
+         *                                   false otherwise.
+         * @return The builder.
+         */
+        public @NonNull Builder setUserAuthenticationRequired(boolean userAuthenticationRequired) {
+            mProfile.mUserAuthenticationRequired = userAuthenticationRequired;
+            return this;
+        }
+
+        /**
+         * Sets the authentication timeout to use.
+         *
+         * <p>The authentication timeout specifies the amount of time, in milliseconds, for which a
+         * user authentication is valid, if user authentication is required (see
+         * {@link #setUserAuthenticationRequired(boolean)}).</p>
+         *
+         * <p>If the timeout is zero, then authentication is always required for each reader
+         * session.</p>
+         *
+         * @param userAuthenticationTimeoutMillis the authentication timeout, in milliseconds.
+         * @return The builder.
+         */
+        public @NonNull Builder setUserAuthenticationTimeout(long userAuthenticationTimeoutMillis) {
+            mProfile.mUserAuthenticationTimeout = userAuthenticationTimeoutMillis;
+            return this;
+        }
+
+        /**
+         * Sets the reader certificate to use when checking access control.
+         *
+         * <p>If set, this is checked against the certificate chain presented by
+         * reader. The access check is fulfilled only if one of the certificates
+         * in the chain, matches the certificate set by this method.</p>
+         *
+         * @param readerCertificate the certificate to use for the access control check.
+         * @return The builder.
+         */
+        public @NonNull Builder setReaderCertificate(@NonNull X509Certificate readerCertificate) {
+            mProfile.mReaderCertificate = readerCertificate;
+            return this;
+        }
+
+        /**
+         * Creates a new {@link AccessControlProfile} from the data supplied to the builder.
+         *
+         * @return The created {@link AccessControlProfile} object.
+         */
+        public @NonNull AccessControlProfile build() {
+            return mProfile;
+        }
+    }
+}
diff --git a/identity/java/android/security/identity/AccessControlProfileId.java b/identity/java/android/security/identity/AccessControlProfileId.java
new file mode 100644
index 0000000..3d59450
--- /dev/null
+++ b/identity/java/android/security/identity/AccessControlProfileId.java
@@ -0,0 +1,42 @@
+/*
+ * 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.security.identity;
+
+/**
+ * A class used to wrap an access control profile identifiers.
+ */
+public class AccessControlProfileId {
+    private int mId = 0;
+
+    /**
+     * Constructs a new object holding a numerical identifier.
+     *
+     * @param id the identifier.
+     */
+    public AccessControlProfileId(int id) {
+        this.mId = id;
+    }
+
+    /**
+     * Gets the numerical identifier wrapped by this object.
+     *
+     * @return the identifier.
+     */
+    public int getId() {
+        return this.mId;
+    }
+}
diff --git a/identity/java/android/security/identity/AlreadyPersonalizedException.java b/identity/java/android/security/identity/AlreadyPersonalizedException.java
new file mode 100644
index 0000000..1933882
--- /dev/null
+++ b/identity/java/android/security/identity/AlreadyPersonalizedException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if trying to create a credential which already exists.
+ */
+public class AlreadyPersonalizedException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link AlreadyPersonalizedException} exception.
+     *
+     * @param message the detail message.
+     */
+    public AlreadyPersonalizedException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link AlreadyPersonalizedException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public AlreadyPersonalizedException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/CipherSuiteNotSupportedException.java b/identity/java/android/security/identity/CipherSuiteNotSupportedException.java
new file mode 100644
index 0000000..e7a6c89
--- /dev/null
+++ b/identity/java/android/security/identity/CipherSuiteNotSupportedException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if trying to use a cipher suite which isn't supported.
+ */
+public class CipherSuiteNotSupportedException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link CipherSuiteNotSupportedException} exception.
+     *
+     * @param message the detail message.
+     */
+    public CipherSuiteNotSupportedException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link CipherSuiteNotSupportedException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public CipherSuiteNotSupportedException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredential.java b/identity/java/android/security/identity/CredstoreIdentityCredential.java
new file mode 100644
index 0000000..c520331
--- /dev/null
+++ b/identity/java/android/security/identity/CredstoreIdentityCredential.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Map;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyAgreement;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+class CredstoreIdentityCredential extends IdentityCredential {
+
+    private static final String TAG = "CredstoreIdentityCredential";
+    private String mCredentialName;
+    private @IdentityCredentialStore.Ciphersuite int mCipherSuite;
+    private Context mContext;
+    private ICredential mBinder;
+
+    CredstoreIdentityCredential(Context context, String credentialName,
+            @IdentityCredentialStore.Ciphersuite int cipherSuite,
+            ICredential binder) {
+        mContext = context;
+        mCredentialName = credentialName;
+        mCipherSuite = cipherSuite;
+        mBinder = binder;
+    }
+
+    private KeyPair mEphemeralKeyPair = null;
+    private SecretKey mSecretKey = null;
+    private SecretKey mReaderSecretKey = null;
+    private int mEphemeralCounter;
+    private int mReadersExpectedEphemeralCounter;
+
+    private void ensureEphemeralKeyPair() {
+        if (mEphemeralKeyPair != null) {
+            return;
+        }
+        try {
+            // This PKCS#12 blob is generated in credstore, using BoringSSL.
+            //
+            // The main reason for this convoluted approach and not just sending the decomposed
+            // key-pair is that this would require directly using (device-side) BouncyCastle which
+            // is tricky due to various API hiding efforts. So instead we have credstore generate
+            // this PKCS#12 blob. The blob is encrypted with no password (sadly, also, BoringSSL
+            // doesn't support not using encryption when building a PKCS#12 blob).
+            //
+            byte[] pkcs12 = mBinder.createEphemeralKeyPair();
+            String alias = "ephemeralKey";
+            char[] password = {};
+
+            KeyStore ks = KeyStore.getInstance("PKCS12");
+            ByteArrayInputStream bais = new ByteArrayInputStream(pkcs12);
+            ks.load(bais, password);
+            PrivateKey privKey = (PrivateKey) ks.getKey(alias, password);
+
+            Certificate cert = ks.getCertificate(alias);
+            PublicKey pubKey = cert.getPublicKey();
+
+            mEphemeralKeyPair = new KeyPair(pubKey, privKey);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        } catch (KeyStoreException
+                | CertificateException
+                | UnrecoverableKeyException
+                | NoSuchAlgorithmException
+                | IOException e) {
+            throw new RuntimeException("Unexpected exception ", e);
+        }
+    }
+
+    @Override
+    public @NonNull KeyPair createEphemeralKeyPair() {
+        ensureEphemeralKeyPair();
+        return mEphemeralKeyPair;
+    }
+
+    @Override
+    public void setReaderEphemeralPublicKey(@NonNull PublicKey readerEphemeralPublicKey)
+            throws InvalidKeyException {
+        try {
+            byte[] uncompressedForm =
+                    Util.publicKeyEncodeUncompressedForm(readerEphemeralPublicKey);
+            mBinder.setReaderEphemeralPublicKey(uncompressedForm);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+
+        ensureEphemeralKeyPair();
+
+        try {
+            KeyAgreement ka = KeyAgreement.getInstance("ECDH");
+            ka.init(mEphemeralKeyPair.getPrivate());
+            ka.doPhase(readerEphemeralPublicKey, true);
+            byte[] sharedSecret = ka.generateSecret();
+
+            byte[] salt = new byte[1];
+            byte[] info = new byte[0];
+
+            salt[0] = 0x01;
+            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            mSecretKey = new SecretKeySpec(derivedKey, "AES");
+
+            salt[0] = 0x00;
+            derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            mReaderSecretKey = new SecretKeySpec(derivedKey, "AES");
+
+            mEphemeralCounter = 0;
+            mReadersExpectedEphemeralCounter = 0;
+
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("Error performing key agreement", e);
+        }
+    }
+
+    @Override
+    public @NonNull byte[] encryptMessageToReader(@NonNull byte[] messagePlaintext) {
+        byte[] messageCiphertextAndAuthTag = null;
+        try {
+            ByteBuffer iv = ByteBuffer.allocate(12);
+            iv.putInt(0, 0x00000000);
+            iv.putInt(4, 0x00000001);
+            iv.putInt(8, mEphemeralCounter);
+            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+            GCMParameterSpec encryptionParameterSpec = new GCMParameterSpec(128, iv.array());
+            cipher.init(Cipher.ENCRYPT_MODE, mSecretKey, encryptionParameterSpec);
+            messageCiphertextAndAuthTag = cipher.doFinal(messagePlaintext);
+        } catch (BadPaddingException
+                | IllegalBlockSizeException
+                | NoSuchPaddingException
+                | InvalidKeyException
+                | NoSuchAlgorithmException
+                | InvalidAlgorithmParameterException e) {
+            throw new RuntimeException("Error encrypting message", e);
+        }
+        mEphemeralCounter += 1;
+        return messageCiphertextAndAuthTag;
+    }
+
+    @Override
+    public @NonNull byte[] decryptMessageFromReader(@NonNull byte[] messageCiphertext)
+            throws MessageDecryptionException {
+        ByteBuffer iv = ByteBuffer.allocate(12);
+        iv.putInt(0, 0x00000000);
+        iv.putInt(4, 0x00000000);
+        iv.putInt(8, mReadersExpectedEphemeralCounter);
+        byte[] plainText = null;
+        try {
+            final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+            cipher.init(Cipher.DECRYPT_MODE, mReaderSecretKey,
+                    new GCMParameterSpec(128, iv.array()));
+            plainText = cipher.doFinal(messageCiphertext);
+        } catch (BadPaddingException
+                | IllegalBlockSizeException
+                | InvalidAlgorithmParameterException
+                | InvalidKeyException
+                | NoSuchAlgorithmException
+                | NoSuchPaddingException e) {
+            throw new MessageDecryptionException("Error decrypting message", e);
+        }
+        mReadersExpectedEphemeralCounter += 1;
+        return plainText;
+    }
+
+    @Override
+    public @NonNull Collection<X509Certificate> getCredentialKeyCertificateChain() {
+        try {
+            byte[] certsBlob = mBinder.getCredentialKeyCertificateChain();
+            ByteArrayInputStream bais = new ByteArrayInputStream(certsBlob);
+
+            Collection<? extends Certificate> certs = null;
+            try {
+                CertificateFactory factory = CertificateFactory.getInstance("X.509");
+                certs = factory.generateCertificates(bais);
+            } catch (CertificateException e) {
+                throw new RuntimeException("Error decoding certificates", e);
+            }
+
+            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+            for (Certificate cert : certs) {
+                x509Certs.add((X509Certificate) cert);
+            }
+            return x509Certs;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    private boolean mAllowUsingExhaustedKeys = true;
+
+    @Override
+    public void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) {
+        mAllowUsingExhaustedKeys = allowUsingExhaustedKeys;
+    }
+
+    private boolean mOperationHandleSet = false;
+    private long mOperationHandle = 0;
+
+    /**
+     * Called by android.hardware.biometrics.CryptoObject#getOpId() to get an
+     * operation handle.
+     *
+     * @hide
+     */
+    @Override
+    public long getCredstoreOperationHandle() {
+        if (!mOperationHandleSet) {
+            try {
+                mOperationHandle = mBinder.selectAuthKey(mAllowUsingExhaustedKeys);
+                mOperationHandleSet = true;
+            } catch (android.os.RemoteException e) {
+                throw new RuntimeException("Unexpected RemoteException ", e);
+            } catch (android.os.ServiceSpecificException e) {
+                if (e.errorCode == ICredentialStore.ERROR_NO_AUTHENTICATION_KEY_AVAILABLE) {
+                    // The NoAuthenticationKeyAvailableException will be thrown when
+                    // the caller proceeds to call getEntries().
+                }
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+        return mOperationHandle;
+    }
+
+    @NonNull
+    @Override
+    public ResultData getEntries(
+            @Nullable byte[] requestMessage,
+            @NonNull Map<String, Collection<String>> entriesToRequest,
+            @Nullable byte[] sessionTranscript,
+            @Nullable byte[] readerSignature)
+            throws SessionTranscriptMismatchException, NoAuthenticationKeyAvailableException,
+            InvalidReaderSignatureException, EphemeralPublicKeyNotFoundException,
+            InvalidRequestMessageException {
+
+        RequestNamespaceParcel[] rnsParcels = new RequestNamespaceParcel[entriesToRequest.size()];
+        int n = 0;
+        for (String namespaceName : entriesToRequest.keySet()) {
+            Collection<String> entryNames = entriesToRequest.get(namespaceName);
+            rnsParcels[n] = new RequestNamespaceParcel();
+            rnsParcels[n].namespaceName = namespaceName;
+            rnsParcels[n].entries = new RequestEntryParcel[entryNames.size()];
+            int m = 0;
+            for (String entryName : entryNames) {
+                rnsParcels[n].entries[m] = new RequestEntryParcel();
+                rnsParcels[n].entries[m].name = entryName;
+                m++;
+            }
+            n++;
+        }
+
+        GetEntriesResultParcel resultParcel = null;
+        try {
+            resultParcel = mBinder.getEntries(
+                requestMessage != null ? requestMessage : new byte[0],
+                rnsParcels,
+                sessionTranscript != null ? sessionTranscript : new byte[0],
+                readerSignature != null ? readerSignature : new byte[0],
+                mAllowUsingExhaustedKeys);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_EPHEMERAL_PUBLIC_KEY_NOT_FOUND) {
+                throw new EphemeralPublicKeyNotFoundException(e.getMessage(), e);
+            } else if (e.errorCode == ICredentialStore.ERROR_INVALID_READER_SIGNATURE) {
+                throw new InvalidReaderSignatureException(e.getMessage(), e);
+            } else if (e.errorCode == ICredentialStore.ERROR_NO_AUTHENTICATION_KEY_AVAILABLE) {
+                throw new NoAuthenticationKeyAvailableException(e.getMessage(), e);
+            } else if (e.errorCode == ICredentialStore.ERROR_INVALID_ITEMS_REQUEST_MESSAGE) {
+                throw new InvalidRequestMessageException(e.getMessage(), e);
+            } else if (e.errorCode == ICredentialStore.ERROR_SESSION_TRANSCRIPT_MISMATCH) {
+                throw new SessionTranscriptMismatchException(e.getMessage(), e);
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+
+        byte[] mac = resultParcel.mac;
+        if (mac != null && mac.length == 0) {
+            mac = null;
+        }
+        CredstoreResultData.Builder resultDataBuilder = new CredstoreResultData.Builder(
+                resultParcel.staticAuthenticationData, resultParcel.deviceNameSpaces, mac);
+
+        for (ResultNamespaceParcel resultNamespaceParcel : resultParcel.resultNamespaces) {
+            for (ResultEntryParcel resultEntryParcel : resultNamespaceParcel.entries) {
+                if (resultEntryParcel.status == ICredential.STATUS_OK) {
+                    resultDataBuilder.addEntry(resultNamespaceParcel.namespaceName,
+                            resultEntryParcel.name, resultEntryParcel.value);
+                } else {
+                    resultDataBuilder.addErrorStatus(resultNamespaceParcel.namespaceName,
+                            resultEntryParcel.name,
+                            resultEntryParcel.status);
+                }
+            }
+        }
+        return resultDataBuilder.build();
+    }
+
+    @Override
+    public void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey) {
+        try {
+            mBinder.setAvailableAuthenticationKeys(keyCount, maxUsesPerKey);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    @Override
+    public @NonNull Collection<X509Certificate> getAuthKeysNeedingCertification() {
+        try {
+            AuthKeyParcel[] authKeyParcels = mBinder.getAuthKeysNeedingCertification();
+            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+            CertificateFactory factory = CertificateFactory.getInstance("X.509");
+            for (AuthKeyParcel authKeyParcel : authKeyParcels) {
+                Collection<? extends Certificate> certs = null;
+                ByteArrayInputStream bais = new ByteArrayInputStream(authKeyParcel.x509cert);
+                certs = factory.generateCertificates(bais);
+                if (certs.size() != 1) {
+                    throw new RuntimeException("Returned blob yields more than one X509 cert");
+                }
+                X509Certificate authKeyCert = (X509Certificate) certs.iterator().next();
+                x509Certs.add(authKeyCert);
+            }
+            return x509Certs;
+        } catch (CertificateException e) {
+            throw new RuntimeException("Error decoding authenticationKey", e);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    @Override
+    public void storeStaticAuthenticationData(X509Certificate authenticationKey,
+            byte[] staticAuthData)
+            throws UnknownAuthenticationKeyException {
+        try {
+            AuthKeyParcel authKeyParcel = new AuthKeyParcel();
+            authKeyParcel.x509cert = authenticationKey.getEncoded();
+            mBinder.storeStaticAuthenticationData(authKeyParcel, staticAuthData);
+        } catch (CertificateEncodingException e) {
+            throw new RuntimeException("Error encoding authenticationKey", e);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_AUTHENTICATION_KEY_NOT_FOUND) {
+                throw new UnknownAuthenticationKeyException(e.getMessage(), e);
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+    }
+
+    @Override
+    public @NonNull int[] getAuthenticationDataUsageCount() {
+        try {
+            int[] usageCount = mBinder.getAuthenticationDataUsageCount();
+            return usageCount;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+}
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java b/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java
new file mode 100644
index 0000000..dcc6b95
--- /dev/null
+++ b/identity/java/android/security/identity/CredstoreIdentityCredentialStore.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.ServiceManager;
+
+class CredstoreIdentityCredentialStore extends IdentityCredentialStore {
+
+    private static final String TAG = "CredstoreIdentityCredentialStore";
+
+    private Context mContext = null;
+    private ICredentialStore mStore = null;
+
+    private CredstoreIdentityCredentialStore(@NonNull Context context, ICredentialStore store) {
+        mContext = context;
+        mStore = store;
+    }
+
+    static CredstoreIdentityCredentialStore getInstanceForType(@NonNull Context context,
+            int credentialStoreType) {
+        ICredentialStoreFactory storeFactory =
+                ICredentialStoreFactory.Stub.asInterface(
+                    ServiceManager.getService("android.security.identity"));
+
+        ICredentialStore credStore = null;
+        try {
+            credStore = storeFactory.getCredentialStore(credentialStoreType);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_GENERIC) {
+                return null;
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+        if (credStore == null) {
+            return null;
+        }
+
+        return new CredstoreIdentityCredentialStore(context, credStore);
+    }
+
+    private static CredstoreIdentityCredentialStore sInstanceDefault = null;
+    private static CredstoreIdentityCredentialStore sInstanceDirectAccess = null;
+
+    public static @Nullable IdentityCredentialStore getInstance(@NonNull Context context) {
+        if (sInstanceDefault == null) {
+            sInstanceDefault = getInstanceForType(context,
+                    ICredentialStoreFactory.CREDENTIAL_STORE_TYPE_DEFAULT);
+        }
+        return sInstanceDefault;
+    }
+
+    public static @Nullable IdentityCredentialStore getDirectAccessInstance(@NonNull
+            Context context) {
+        if (sInstanceDirectAccess == null) {
+            sInstanceDirectAccess = getInstanceForType(context,
+                    ICredentialStoreFactory.CREDENTIAL_STORE_TYPE_DIRECT_ACCESS);
+        }
+        return sInstanceDirectAccess;
+    }
+
+    @Override
+    public @NonNull String[] getSupportedDocTypes() {
+        try {
+            SecurityHardwareInfoParcel info;
+            info = mStore.getSecurityHardwareInfo();
+            return info.supportedDocTypes;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    @Override public @NonNull WritableIdentityCredential createCredential(
+            @NonNull String credentialName,
+            @NonNull String docType) throws AlreadyPersonalizedException,
+            DocTypeNotSupportedException {
+        try {
+            IWritableCredential wc;
+            wc = mStore.createCredential(credentialName, docType);
+            return new CredstoreWritableIdentityCredential(mContext, credentialName, docType, wc);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_ALREADY_PERSONALIZED) {
+                throw new AlreadyPersonalizedException(e.getMessage(), e);
+            } else if (e.errorCode == ICredentialStore.ERROR_DOCUMENT_TYPE_NOT_SUPPORTED) {
+                throw new DocTypeNotSupportedException(e.getMessage(), e);
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+    }
+
+    @Override public @Nullable IdentityCredential getCredentialByName(
+            @NonNull String credentialName,
+            @Ciphersuite int cipherSuite) throws CipherSuiteNotSupportedException {
+        try {
+            ICredential credstoreCredential;
+            credstoreCredential = mStore.getCredentialByName(credentialName, cipherSuite);
+            return new CredstoreIdentityCredential(mContext, credentialName, cipherSuite,
+                    credstoreCredential);
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            if (e.errorCode == ICredentialStore.ERROR_NO_SUCH_CREDENTIAL) {
+                return null;
+            } else if (e.errorCode == ICredentialStore.ERROR_CIPHER_SUITE_NOT_SUPPORTED) {
+                throw new CipherSuiteNotSupportedException(e.getMessage(), e);
+            } else {
+                throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                        + e.errorCode, e);
+            }
+        }
+    }
+
+    @Override
+    public @Nullable byte[] deleteCredentialByName(@NonNull String credentialName) {
+        ICredential credstoreCredential = null;
+        try {
+            try {
+                credstoreCredential = mStore.getCredentialByName(credentialName,
+                        CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256);
+            } catch (android.os.ServiceSpecificException e) {
+                if (e.errorCode == ICredentialStore.ERROR_NO_SUCH_CREDENTIAL) {
+                    return null;
+                }
+            }
+            byte[] proofOfDeletion = credstoreCredential.deleteCredential();
+            return proofOfDeletion;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+}
diff --git a/identity/java/android/security/identity/CredstoreResultData.java b/identity/java/android/security/identity/CredstoreResultData.java
new file mode 100644
index 0000000..ef7afca
--- /dev/null
+++ b/identity/java/android/security/identity/CredstoreResultData.java
@@ -0,0 +1,162 @@
+/*
+ * 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.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * An object that contains the result of retrieving data from a credential. This is used to return
+ * data requested from a {@link IdentityCredential}.
+ */
+class CredstoreResultData extends ResultData {
+
+    byte[] mStaticAuthenticationData = null;
+    byte[] mAuthenticatedData = null;
+    byte[] mMessageAuthenticationCode = null;
+
+    private Map<String, Map<String, EntryData>> mData = new LinkedHashMap<>();
+
+    private static class EntryData {
+        @Status
+        int mStatus;
+        byte[] mValue;
+
+        EntryData(byte[] value, @Status int status) {
+            this.mValue = value;
+            this.mStatus = status;
+        }
+    }
+
+    CredstoreResultData() {}
+
+    @Override
+    public @NonNull byte[] getAuthenticatedData() {
+        return mAuthenticatedData;
+    }
+
+    @Override
+    public @Nullable byte[] getMessageAuthenticationCode() {
+        return mMessageAuthenticationCode;
+    }
+
+    @Override
+    public @NonNull byte[] getStaticAuthenticationData() {
+        return mStaticAuthenticationData;
+    }
+
+    @Override
+    public @NonNull Collection<String> getNamespaceNames() {
+        return Collections.unmodifiableCollection(mData.keySet());
+    }
+
+    @Override
+    public @Nullable Collection<String> getEntryNames(@NonNull String namespaceName) {
+        Map<String, EntryData> innerMap = mData.get(namespaceName);
+        if (innerMap == null) {
+            return null;
+        }
+        return Collections.unmodifiableCollection(innerMap.keySet());
+    }
+
+    @Override
+    public @Nullable Collection<String> getRetrievedEntryNames(@NonNull String namespaceName) {
+        Map<String, EntryData> innerMap = mData.get(namespaceName);
+        if (innerMap == null) {
+            return null;
+        }
+        LinkedList<String> result = new LinkedList<String>();
+        for (Map.Entry<String, EntryData> entry : innerMap.entrySet()) {
+            if (entry.getValue().mStatus == STATUS_OK) {
+                result.add(entry.getKey());
+            }
+        }
+        return result;
+    }
+
+    private EntryData getEntryData(@NonNull String namespaceName, @NonNull String name) {
+        Map<String, EntryData> innerMap = mData.get(namespaceName);
+        if (innerMap == null) {
+            return null;
+        }
+        return innerMap.get(name);
+    }
+
+    @Override
+    @Status
+    public int getStatus(@NonNull String namespaceName, @NonNull String name) {
+        EntryData value = getEntryData(namespaceName, name);
+        if (value == null) {
+            return STATUS_NOT_REQUESTED;
+        }
+        return value.mStatus;
+    }
+
+    @Override
+    public @Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name) {
+        EntryData value = getEntryData(namespaceName, name);
+        if (value == null) {
+            return null;
+        }
+        return value.mValue;
+    }
+
+    static class Builder {
+        private CredstoreResultData mResultData;
+
+        Builder(byte[] staticAuthenticationData,
+                byte[] authenticatedData,
+                byte[] messageAuthenticationCode) {
+            this.mResultData = new CredstoreResultData();
+            this.mResultData.mStaticAuthenticationData = staticAuthenticationData;
+            this.mResultData.mAuthenticatedData = authenticatedData;
+            this.mResultData.mMessageAuthenticationCode = messageAuthenticationCode;
+        }
+
+        private Map<String, EntryData> getOrCreateInnerMap(String namespaceName) {
+            Map<String, EntryData> innerMap = mResultData.mData.get(namespaceName);
+            if (innerMap == null) {
+                innerMap = new LinkedHashMap<>();
+                mResultData.mData.put(namespaceName, innerMap);
+            }
+            return innerMap;
+        }
+
+        Builder addEntry(String namespaceName, String name, byte[] value) {
+            Map<String, EntryData> innerMap = getOrCreateInnerMap(namespaceName);
+            innerMap.put(name, new EntryData(value, STATUS_OK));
+            return this;
+        }
+
+        Builder addErrorStatus(String namespaceName, String name, @Status int status) {
+            Map<String, EntryData> innerMap = getOrCreateInnerMap(namespaceName);
+            innerMap.put(name, new EntryData(null, status));
+            return this;
+        }
+
+        CredstoreResultData build() {
+            return mResultData;
+        }
+    }
+
+}
diff --git a/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java b/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
new file mode 100644
index 0000000..335636c
--- /dev/null
+++ b/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.security.GateKeeper;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.LinkedList;
+
+class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
+
+    private static final String TAG = "CredstoreWritableIdentityCredential";
+
+    private String mDocType;
+    private String mCredentialName;
+    private Context mContext;
+    private IWritableCredential mBinder;
+
+    CredstoreWritableIdentityCredential(Context context,
+            @NonNull String credentialName,
+            @NonNull String docType,
+            IWritableCredential binder) {
+        mContext = context;
+        mDocType = docType;
+        mCredentialName = credentialName;
+        mBinder = binder;
+    }
+
+    @NonNull @Override
+    public Collection<X509Certificate> getCredentialKeyCertificateChain(@NonNull byte[] challenge) {
+        try {
+            byte[] certsBlob = mBinder.getCredentialKeyCertificateChain(challenge);
+            ByteArrayInputStream bais = new ByteArrayInputStream(certsBlob);
+
+            Collection<? extends Certificate> certs = null;
+            try {
+                CertificateFactory factory = CertificateFactory.getInstance("X.509");
+                certs = factory.generateCertificates(bais);
+            } catch (CertificateException e) {
+                throw new RuntimeException("Error decoding certificates", e);
+            }
+
+            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+            for (Certificate cert : certs) {
+                x509Certs.add((X509Certificate) cert);
+            }
+            return x509Certs;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    @NonNull @Override
+    public byte[] personalize(@NonNull PersonalizationData personalizationData) {
+
+        Collection<AccessControlProfile> accessControlProfiles =
+                personalizationData.getAccessControlProfiles();
+
+        AccessControlProfileParcel[] acpParcels =
+                new AccessControlProfileParcel[accessControlProfiles.size()];
+        boolean usingUserAuthentication = false;
+        int n = 0;
+        for (AccessControlProfile profile : accessControlProfiles) {
+            acpParcels[n] = new AccessControlProfileParcel();
+            acpParcels[n].id = profile.getAccessControlProfileId().getId();
+            X509Certificate cert = profile.getReaderCertificate();
+            if (cert != null) {
+                try {
+                    acpParcels[n].readerCertificate = cert.getEncoded();
+                } catch (CertificateException e) {
+                    throw new RuntimeException("Error encoding reader certificate", e);
+                }
+            } else {
+                acpParcels[n].readerCertificate = new byte[0];
+            }
+            acpParcels[n].userAuthenticationRequired = profile.isUserAuthenticationRequired();
+            acpParcels[n].userAuthenticationTimeoutMillis = profile.getUserAuthenticationTimeout();
+            if (profile.isUserAuthenticationRequired()) {
+                usingUserAuthentication = true;
+            }
+            n++;
+        }
+
+        Collection<String> namespaceNames = personalizationData.getNamespaceNames();
+
+        EntryNamespaceParcel[] ensParcels  = new EntryNamespaceParcel[namespaceNames.size()];
+        n = 0;
+        for (String namespaceName : namespaceNames) {
+            PersonalizationData.NamespaceData nsd =
+                    personalizationData.getNamespaceData(namespaceName);
+
+            ensParcels[n] = new EntryNamespaceParcel();
+            ensParcels[n].namespaceName = namespaceName;
+
+            Collection<String> entryNames = nsd.getEntryNames();
+            EntryParcel[] eParcels = new EntryParcel[entryNames.size()];
+            int m = 0;
+            for (String entryName : entryNames) {
+                eParcels[m] = new EntryParcel();
+                eParcels[m].name = entryName;
+                eParcels[m].value = nsd.getEntryValue(entryName);
+                Collection<AccessControlProfileId> acpIds =
+                        nsd.getAccessControlProfileIds(entryName);
+                eParcels[m].accessControlProfileIds = new int[acpIds.size()];
+                int o = 0;
+                for (AccessControlProfileId acpId : acpIds) {
+                    eParcels[m].accessControlProfileIds[o++] = acpId.getId();
+                }
+                m++;
+            }
+            ensParcels[n].entries = eParcels;
+            n++;
+        }
+
+        // Note: The value 0 is used to convey that no user-authentication is needed for this
+        // credential. This is to allow creating credentials w/o user authentication on devices
+        // where Secure lock screen is not enabled.
+        long secureUserId = 0;
+        if (usingUserAuthentication) {
+            secureUserId = getRootSid();
+        }
+        try {
+            byte[] personalizationReceipt = mBinder.personalize(acpParcels, ensParcels,
+                    secureUserId);
+            return personalizationReceipt;
+        } catch (android.os.RemoteException e) {
+            throw new RuntimeException("Unexpected RemoteException ", e);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new RuntimeException("Unexpected ServiceSpecificException with code "
+                    + e.errorCode, e);
+        }
+    }
+
+    private static long getRootSid() {
+        long rootSid = GateKeeper.getSecureUserId();
+        if (rootSid == 0) {
+            throw new IllegalStateException("Secure lock screen must be enabled"
+                    + " to create credentials requiring user authentication");
+        }
+        return rootSid;
+    }
+
+
+}
diff --git a/identity/java/android/security/identity/DocTypeNotSupportedException.java b/identity/java/android/security/identity/DocTypeNotSupportedException.java
new file mode 100644
index 0000000..754e44a
--- /dev/null
+++ b/identity/java/android/security/identity/DocTypeNotSupportedException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if trying to create a credential with an unsupported document type.
+ */
+public class DocTypeNotSupportedException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link DocTypeNotSupportedException} exception.
+     *
+     * @param message the detail message.
+     */
+    public DocTypeNotSupportedException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link DocTypeNotSupportedException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public DocTypeNotSupportedException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/EphemeralPublicKeyNotFoundException.java b/identity/java/android/security/identity/EphemeralPublicKeyNotFoundException.java
new file mode 100644
index 0000000..265f271
--- /dev/null
+++ b/identity/java/android/security/identity/EphemeralPublicKeyNotFoundException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if the ephemeral public key was not found in the session transcript
+ * passed to {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])}.
+ */
+public class EphemeralPublicKeyNotFoundException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link EphemeralPublicKeyNotFoundException} exception.
+     *
+     * @param message the detail message.
+     */
+    public EphemeralPublicKeyNotFoundException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link EphemeralPublicKeyNotFoundException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public EphemeralPublicKeyNotFoundException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/IdentityCredential.java b/identity/java/android/security/identity/IdentityCredential.java
new file mode 100644
index 0000000..bd43919
--- /dev/null
+++ b/identity/java/android/security/identity/IdentityCredential.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Class used to read data from a previously provisioned credential.
+ *
+ * Use {@link IdentityCredentialStore#getCredentialByName(String, int)} to get a
+ * {@link IdentityCredential} instance.
+ */
+public abstract class IdentityCredential {
+    /**
+     * @hide
+     */
+    protected IdentityCredential() {}
+
+    /**
+     * Create an ephemeral key pair to use to establish a secure channel with a reader.
+     *
+     * <p>Most applications will use only the public key, and only to send it to the reader,
+     * allowing the private key to be used internally for {@link #encryptMessageToReader(byte[])}
+     * and {@link #decryptMessageFromReader(byte[])}. The private key is also provided for
+     * applications that wish to use a cipher suite that is not supported by
+     * {@link IdentityCredentialStore}.
+     *
+     * @return ephemeral key pair to use to establish a secure channel with a reader.
+     */
+    public @NonNull abstract KeyPair createEphemeralKeyPair();
+
+    /**
+     * Set the ephemeral public key provided by the reader. This must be called before
+     * {@link #encryptMessageToReader} or {@link #decryptMessageFromReader} can be called.
+     *
+     * @param readerEphemeralPublicKey The ephemeral public key provided by the reader to
+     *                                 establish a secure session.
+     * @throws InvalidKeyException if the given key is invalid.
+     */
+    public abstract void setReaderEphemeralPublicKey(@NonNull PublicKey readerEphemeralPublicKey)
+            throws InvalidKeyException;
+
+    /**
+     * Encrypt a message for transmission to the reader.
+     *
+     * @param messagePlaintext unencrypted message to encrypt.
+     * @return encrypted message.
+     */
+    public @NonNull abstract byte[] encryptMessageToReader(@NonNull byte[] messagePlaintext);
+
+    /**
+     * Decrypt a message received from the reader.
+     *
+     * @param messageCiphertext encrypted message to decrypt.
+     * @return decrypted message.
+     * @throws MessageDecryptionException if the ciphertext couldn't be decrypted.
+     */
+    public @NonNull abstract byte[] decryptMessageFromReader(@NonNull byte[] messageCiphertext)
+            throws MessageDecryptionException;
+
+    /**
+     * Gets the X.509 certificate chain for the CredentialKey which identifies this
+     * credential to the issuing authority. This is the same certificate chain that
+     * was returned by {@link WritableIdentityCredential#getCredentialKeyCertificateChain(byte[])}
+     * when the credential was first created and its Android Keystore extension will
+     * contain the <code>challenge</code> data set at that time. See the documentation
+     * for that method for important information about this certificate chain.
+     *
+     * @return the certificate chain for this credential's CredentialKey.
+     */
+    public @NonNull abstract Collection<X509Certificate> getCredentialKeyCertificateChain();
+
+    /**
+     * Sets whether to allow using an authentication key which use count has been exceeded if no
+     * other key is available. This must be called prior to calling
+     * {@link #getEntries(byte[], Map, byte[], byte[])} or using a
+     * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this
+     * object.
+     *
+     * By default this is set to true.
+     *
+     * @param allowUsingExhaustedKeys whether to allow using an authentication key which use count
+     *                                has been exceeded if no other key is available.
+     */
+    public abstract void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys);
+
+    /**
+     * Called by android.hardware.biometrics.CryptoObject#getOpId() to get an
+     * operation handle.
+     *
+     * @hide
+     */
+    public abstract long getCredstoreOperationHandle();
+
+    /**
+     * Retrieve data entries and associated data from this {@code IdentityCredential}.
+     *
+     * <p>If an access control check fails for one of the requested entries or if the entry
+     * doesn't exist, the entry is simply not returned. The application can detect this
+     * by using the {@link ResultData#getStatus(String, String)} method on each of the requested
+     * entries.
+     *
+     * <p>It is the responsibility of the calling application to know if authentication is needed
+     * and use e.g. {@link android.hardware.biometrics.BiometricPrompt}) to make the user
+     * authenticate using a {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which
+     * references this object. If needed, this must be done before calling
+     * {@link #getEntries(byte[], Map, byte[], byte[])}.
+     *
+     * <p>If this method returns successfully (i.e. without throwing an exception), it must not be
+     * called again on this instance.
+     *
+     * <p>If not {@code null} the {@code requestMessage} parameter must contain data for the request
+     * from the verifier. The content can be defined in the way appropriate for the credential, byt
+     * there are three requirements that must be met to work with this API:
+     * <ul>
+     * <li>The content must be a CBOR-encoded structure.</li>
+     * <li>The CBOR structure must be a map.</li>
+     * <li>The map must contain a tstr key "nameSpaces" whose value contains a map, as described in
+     *     the example below.</li>
+     * </ul>
+     *
+     * <p>Here's an example of CBOR which conforms to this requirement:
+     * <pre>
+     *   ItemsRequest = {
+     *     ? "docType" : DocType,
+     *     "nameSpaces" : NameSpaces,
+     *     ? "RequestInfo" : {* tstr => any} ; Additional info the reader wants to provide
+     *   }
+     *
+     *   NameSpaces = {
+     *     + NameSpace => DataElements    ; Requested data elements for each NameSpace
+     *   }
+     *
+     *   NameSpace = tstr
+     *
+     *   DataElements = {
+     *     + DataElement => IntentToRetain
+     *   }
+     *
+     *   DataElement = tstr
+     *   IntentToRetain = bool
+     * </pre>
+     *
+     * <p>If the {@code sessionTranscript} parameter is not {@code null}, it must contain CBOR
+     * data conforming to the following CDDL schema:
+     *
+     * <pre>
+     *   SessionTranscript = [
+     *     DeviceEngagementBytes,
+     *     EReaderKeyBytes
+     *   ]
+     *
+     *   DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
+     *   EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
+     * </pre>
+     *
+     * <p>If the SessionTranscript is not empty, a COSE_Key structure for the public part
+     * of the key-pair previously generated by {@link #createEphemeralKeyPair()} must appear
+     * somewhere in {@code DeviceEngagement} and the X and Y coordinates must both be present
+     * in uncompressed form.
+     *
+     * <p>If {@code readerAuth} is not {@code null} it must be the bytes of a COSE_Sign1
+     * structure as defined in RFC 8152. For the payload nil shall be used and the
+     * detached payload is the ReaderAuthentication CBOR described below.
+     * <pre>
+     *     ReaderAuthentication = [
+     *       "ReaderAuthentication",
+     *       SessionTranscript,
+     *       ItemsRequestBytes
+     *     ]
+     *
+     *     ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)   ; Bytes of ItemsRequest
+     * </pre>
+     *
+     * <p>The public key corresponding to the key used to made signature, can be
+     * found in the {@code x5chain} unprotected header element of the COSE_Sign1
+     * structure (as as described in 'draft-ietf-cose-x509-04'). There will be at
+     * least one certificate in said element and there may be more (and if so,
+     * each certificate must be signed by its successor).
+     *
+     * <p>Data elements protected by reader authentication is returned if, and only if, they are
+     * mentioned in {@code requestMessage}, {@code requestMessage} is signed by the top-most
+     * certificate in {@code readerCertificateChain}, and the data element is configured
+     * with an {@link AccessControlProfile} with a {@link X509Certificate} in
+     * {@code readerCertificateChain}.
+     *
+     * <p>Note that only items referenced in {@code entriesToRequest} are returned - the
+     * {@code requestMessage} parameter is only used to for enforcing reader authentication.
+     *
+     * @param requestMessage         If not {@code null}, must contain CBOR data conforming to
+     *                               the schema mentioned above.
+     * @param entriesToRequest       The entries to request, organized as a map of namespace
+     *                               names with each value being a collection of data elements
+     *                               in the given namespace.
+     * @param readerSignature        COSE_Sign1 structure as described above or {@code null}
+     *                               if reader authentication is not being used.
+     * @return A {@link ResultData} object containing entry data organized by namespace and a
+     *         cryptographically authenticated representation of the same data.
+     * @throws SessionTranscriptMismatchException     Thrown when trying use multiple different
+     *                                                session transcripts in the same presentation
+     *                                                session.
+     * @throws NoAuthenticationKeyAvailableException  if authentication keys were never
+     *                                                provisioned, the method
+     *                                             {@link #setAvailableAuthenticationKeys(int, int)}
+     *                                                was called with {@code keyCount} set to 0,
+     *                                                the method
+     *                                                {@link #setAllowUsingExhaustedKeys(boolean)}
+     *                                                was called with {@code false} and all
+     *                                                available authentication keys have been
+     *                                                exhausted.
+     * @throws InvalidReaderSignatureException        if the reader signature is invalid, or it
+     *                                                doesn't contain a certificate chain, or if
+     *                                                the signature failed to validate.
+     * @throws InvalidRequestMessageException         if the requestMessage is malformed.
+     * @throws EphemeralPublicKeyNotFoundException    if the ephemeral public key was not found in
+     *                                                the session transcript.
+     */
+    public abstract @NonNull ResultData getEntries(
+            @Nullable byte[] requestMessage,
+            @NonNull Map<String, Collection<String>> entriesToRequest,
+            @Nullable byte[] sessionTranscript,
+            @Nullable byte[] readerSignature)
+            throws SessionTranscriptMismatchException, NoAuthenticationKeyAvailableException,
+            InvalidReaderSignatureException, EphemeralPublicKeyNotFoundException,
+            InvalidRequestMessageException;
+
+    /**
+     * Sets the number of dynamic authentication keys the {@code IdentityCredential} will maintain,
+     * and the number of times each should be used.
+     *
+     * <p>{@code IdentityCredential}s will select the least-used dynamic authentication key each
+     * time {@link #getEntries(byte[], Map, byte[], byte[])} is called. {@code IdentityCredential}s
+     * for which this method has not been called behave as though it had been called wit
+     * {@code keyCount} 0 and {@code maxUsesPerKey} 1.
+     *
+     * @param keyCount      The number of active, certified dynamic authentication keys the
+     *                      {@code IdentityCredential} will try to keep available. This value
+     *                      must be non-negative.
+     * @param maxUsesPerKey The maximum number of times each of the keys will be used before it's
+     *                      eligible for replacement. This value must be greater than zero.
+     */
+    public abstract void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey);
+
+    /**
+     * Gets a collection of dynamic authentication keys that need certification.
+     *
+     * <p>When there aren't enough certified dynamic authentication keys, either because the key
+     * count has been increased or because one or more keys have reached their usage count, this
+     * method will generate replacement keys and certificates and return them for issuer
+     * certification. The issuer certificates and associated static authentication data must then
+     * be provided back to the {@code IdentityCredential} using
+     * {@link #storeStaticAuthenticationData(X509Certificate, byte[])}.
+     *
+     * <p>Each X.509 certificate is signed by CredentialKey. The certificate chain for CredentialKey
+     * can be obtained using the {@link #getCredentialKeyCertificateChain()} method.
+     *
+     * @return A collection of X.509 certificates for dynamic authentication keys that need issuer
+     * certification.
+     */
+    public @NonNull abstract Collection<X509Certificate> getAuthKeysNeedingCertification();
+
+    /**
+     * Store authentication data associated with a dynamic authentication key.
+     *
+     * This should only be called for an authenticated key returned by
+     * {@link #getAuthKeysNeedingCertification()}.
+     *
+     * @param authenticationKey The dynamic authentication key for which certification and
+     *                          associated static
+     *                          authentication data is being provided.
+     * @param staticAuthData    Static authentication data provided by the issuer that validates
+     *                          the authenticity
+     *                          and integrity of the credential data fields.
+     * @throws UnknownAuthenticationKeyException If the given authentication key is not recognized.
+     */
+    public abstract void storeStaticAuthenticationData(
+            @NonNull X509Certificate authenticationKey,
+            @NonNull byte[] staticAuthData)
+            throws UnknownAuthenticationKeyException;
+
+    /**
+     * Get the number of times the dynamic authentication keys have been used.
+     *
+     * @return int array of dynamic authentication key usage counts.
+     */
+    public @NonNull abstract int[] getAuthenticationDataUsageCount();
+}
diff --git a/identity/java/android/security/identity/IdentityCredentialException.java b/identity/java/android/security/identity/IdentityCredentialException.java
new file mode 100644
index 0000000..c811380
--- /dev/null
+++ b/identity/java/android/security/identity/IdentityCredentialException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Base class for all Identity Credential exceptions.
+ */
+public class IdentityCredentialException extends Exception {
+    /**
+     * Constructs a new {@link IdentityCredentialException} exception.
+     *
+     * @param message the detail message.
+     */
+    public IdentityCredentialException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link IdentityCredentialException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public IdentityCredentialException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/identity/java/android/security/identity/IdentityCredentialStore.java b/identity/java/android/security/identity/IdentityCredentialStore.java
new file mode 100644
index 0000000..a1dfc77
--- /dev/null
+++ b/identity/java/android/security/identity/IdentityCredentialStore.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An interface to a secure store for user identity documents.
+ *
+ * <p>This interface is deliberately fairly general and abstract.  To the extent possible,
+ * specification of the message formats and semantics of communication with credential
+ * verification devices and issuing authorities (IAs) is out of scope. It provides the
+ * interface with secure storage but a credential-specific Android application will be
+ * required to implement the presentation and verification protocols and processes
+ * appropriate for the specific credential type.
+ *
+ * <p>Multiple credentials can be created.  Each credential comprises:</p>
+ * <ul>
+ * <li>A document type, which is a string.</li>
+ *
+ * <li>A set of namespaces, which serve to disambiguate value names. It is recommended
+ * that namespaces be structured as reverse domain names so that IANA effectively serves
+ * as the namespace registrar.</li>
+ *
+ * <li>For each namespace, a set of name/value pairs, each with an associated set of
+ * access control profile IDs.  Names are strings and values are typed and can be any
+ * value supported by <a href="http://cbor.io/">CBOR</a>.</li>
+ *
+ * <li>A set of access control profiles, each with a profile ID and a specification
+ * of the conditions which satisfy the profile's requirements.</li>
+ *
+ * <li>An asymmetric key pair which is used to authenticate the credential to the Issuing
+ * Authority, called the <em>CredentialKey</em>.</li>
+ *
+ * <li>A set of zero or more named reader authentication public keys, which are used to
+ * authenticate an authorized reader to the credential.</li>
+ *
+ * <li>A set of named signing keys, which are used to sign collections of values and session
+ * transcripts.</li>
+ * </ul>
+ *
+ * <p>Implementing support for user identity documents in secure storage requires dedicated
+ * hardware-backed support and may not always be available.
+ *
+ * <p>Two different credential stores exist - the <em>default</em> store and the
+ * <em>direct access</em> store. Most often credentials will be accessed through the default
+ * store but that requires that the Android device be powered up and fully functional.
+ * It is desirable to allow identity credential usage when the Android device's battery is too
+ * low to boot the Android operating system, so direct access to the secure hardware via NFC
+ * may allow data retrieval, if the secure hardware chooses to implement it.
+ *
+ * <p>Credentials provisioned to the direct access store should <strong>always</strong> use reader
+ * authentication to protect data elements. The reason for this is user authentication or user
+ * approval of data release is not possible when the device is off.
+ */
+public abstract class IdentityCredentialStore {
+    IdentityCredentialStore() {}
+
+    /**
+     * Specifies that the cipher suite that will be used to secure communications between the reader
+     * is:
+     *
+     * <ul>
+     * <li>ECDHE with HKDF-SHA-256 for key agreement.</li>
+     * <li>AES-256 with GCM block mode for authenticated encryption (nonces are incremented by one
+     * for every message).</li>
+     * <li>ECDSA with SHA-256 for signing (used for signing session transcripts to defeat
+     * man-in-the-middle attacks), signing keys are not ephemeral. See {@link IdentityCredential}
+     * for details on reader and prover signing keys.</li>
+     * </ul>
+     *
+     * <p>
+     * At present this is the only supported cipher suite.
+     */
+    public static final int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1;
+
+    /**
+     * Gets the default {@link IdentityCredentialStore}.
+     *
+     * @param context the application context.
+     * @return the {@link IdentityCredentialStore} or {@code null} if the device doesn't
+     *     have hardware-backed support for secure storage of user identity documents.
+     */
+    public static @Nullable IdentityCredentialStore getInstance(@NonNull Context context) {
+        return CredstoreIdentityCredentialStore.getInstance(context);
+    }
+
+    /**
+     * Gets the {@link IdentityCredentialStore} for direct access.
+     *
+     * <p>Direct access requires specialized NFC hardware and may not be supported on all
+     * devices even if default store is available. Credentials provisioned to the direct
+     * access store should <strong>always</strong> use reader authentication to protect
+     * data elements.
+     *
+     * @param context the application context.
+     * @return the {@link IdentityCredentialStore} or {@code null} if direct access is not
+     *     supported on this device.
+     */
+    public static @Nullable IdentityCredentialStore getDirectAccessInstance(@NonNull
+            Context context) {
+        return CredstoreIdentityCredentialStore.getDirectAccessInstance(context);
+    }
+
+    /**
+     * Gets a list of supported document types.
+     *
+     * <p>Only the direct-access store may restrict the kind of document types that can be used for
+     * credentials. The default store always supports any document type.
+     *
+     * @return The supported document types or the empty array if any document type is supported.
+     */
+    public abstract @NonNull String[] getSupportedDocTypes();
+
+    /**
+     * Creates a new credential.
+     *
+     * @param credentialName The name used to identify the credential.
+     * @param docType        The document type for the credential.
+     * @return A @{link WritableIdentityCredential} that can be used to create a new credential.
+     * @throws AlreadyPersonalizedException if a credential with the given name already exists.
+     * @throws DocTypeNotSupportedException if the given document type isn't supported by the store.
+     */
+    public abstract @NonNull WritableIdentityCredential createCredential(
+            @NonNull String credentialName, @NonNull String docType)
+            throws AlreadyPersonalizedException, DocTypeNotSupportedException;
+
+    /**
+     * Retrieve a named credential.
+     *
+     * @param credentialName the name of the credential to retrieve.
+     * @param cipherSuite    the cipher suite to use for communicating with the verifier.
+     * @return The named credential, or null if not found.
+     */
+    public abstract @Nullable IdentityCredential getCredentialByName(@NonNull String credentialName,
+            @Ciphersuite int cipherSuite)
+            throws CipherSuiteNotSupportedException;
+
+    /**
+     * Delete a named credential.
+     *
+     * <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey
+     * with payload set to {@code ProofOfDeletion} as defined below:
+     *
+     * <pre>
+     *     ProofOfDeletion = [
+     *          "ProofOfDeletion",            ; tstr
+     *          tstr,                         ; DocType
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *      ]
+     * </pre>
+     *
+     * @param credentialName the name of the credential to delete.
+     * @return {@code null} if the credential was not found, the COSE_Sign1 data structure above
+     *     if the credential was found and deleted.
+     */
+    public abstract @Nullable byte[] deleteCredentialByName(@NonNull String credentialName);
+
+    /** @hide */
+    @IntDef(value = {CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Ciphersuite {
+    }
+
+}
diff --git a/identity/java/android/security/identity/InvalidReaderSignatureException.java b/identity/java/android/security/identity/InvalidReaderSignatureException.java
new file mode 100644
index 0000000..3f70270
--- /dev/null
+++ b/identity/java/android/security/identity/InvalidReaderSignatureException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if the reader signature is invalid, or it doesn't contain a certificate chain, or if the
+ * signature failed to validate.
+ */
+public class InvalidReaderSignatureException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link InvalidReaderSignatureException} exception.
+     *
+     * @param message the detail message.
+     */
+    public InvalidReaderSignatureException(@NonNull String message) {
+        super(message);
+    }
+
+
+    /**
+     * Constructs a new {@link InvalidReaderSignatureException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public InvalidReaderSignatureException(@NonNull String message,
+            @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/InvalidRequestMessageException.java b/identity/java/android/security/identity/InvalidRequestMessageException.java
new file mode 100644
index 0000000..b0c073c
--- /dev/null
+++ b/identity/java/android/security/identity/InvalidRequestMessageException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if message with the request doesn't satisfy the requirements documented in
+ * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])}.
+ */
+public class InvalidRequestMessageException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link InvalidRequestMessageException} exception.
+     *
+     * @param message the detail message.
+     */
+    public InvalidRequestMessageException(@NonNull String message) {
+        super(message);
+    }
+
+
+    /**
+     * Constructs a new {@link InvalidRequestMessageException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public InvalidRequestMessageException(@NonNull String message,
+            @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/MessageDecryptionException.java b/identity/java/android/security/identity/MessageDecryptionException.java
new file mode 100644
index 0000000..7a6169e
--- /dev/null
+++ b/identity/java/android/security/identity/MessageDecryptionException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown when failing to decrypt a message from the reader device.
+ */
+public class MessageDecryptionException extends IdentityCredentialException {
+
+    /**
+     * Constructs a new {@link MessageDecryptionException} exception.
+     *
+     * @param message the detail message.
+     */
+    public MessageDecryptionException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link MessageDecryptionException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public MessageDecryptionException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/NoAuthenticationKeyAvailableException.java b/identity/java/android/security/identity/NoAuthenticationKeyAvailableException.java
new file mode 100644
index 0000000..7f40403
--- /dev/null
+++ b/identity/java/android/security/identity/NoAuthenticationKeyAvailableException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if no dynamic authentication keys are available.
+ */
+public class NoAuthenticationKeyAvailableException extends IdentityCredentialException {
+
+    /**
+     * Constructs a new {@link NoAuthenticationKeyAvailableException} exception.
+     *
+     * @param message the detail message.
+     */
+    public NoAuthenticationKeyAvailableException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link NoAuthenticationKeyAvailableException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public NoAuthenticationKeyAvailableException(@NonNull String message,
+            @NonNull Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/identity/java/android/security/identity/PersonalizationData.java b/identity/java/android/security/identity/PersonalizationData.java
new file mode 100644
index 0000000..44370a1
--- /dev/null
+++ b/identity/java/android/security/identity/PersonalizationData.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+
+/**
+ * An object that holds personalization data.
+ *
+ * This data includes access control profiles and a set of data entries and values, grouped by
+ * namespace.
+ *
+ * This is used to provision data into a {@link WritableIdentityCredential}.
+ *
+ * @see WritableIdentityCredential#personalize
+ */
+public class PersonalizationData {
+
+    private PersonalizationData() {
+    }
+
+    private LinkedList<AccessControlProfile> mProfiles = new LinkedList<>();
+
+    private LinkedHashMap<String, NamespaceData> mNamespaces = new LinkedHashMap<>();
+
+    Collection<AccessControlProfile> getAccessControlProfiles() {
+        return Collections.unmodifiableCollection(mProfiles);
+    }
+
+    Collection<String> getNamespaceNames() {
+        return Collections.unmodifiableCollection(mNamespaces.keySet());
+    }
+
+    NamespaceData getNamespaceData(String namespace) {
+        return mNamespaces.get(namespace);
+    }
+
+    static class NamespaceData {
+
+        private String mNamespace;
+        private LinkedHashMap<String, EntryData> mEntries = new LinkedHashMap<>();
+
+        private NamespaceData(String namespace) {
+            this.mNamespace = namespace;
+        }
+
+        String getNamespaceName() {
+            return mNamespace;
+        }
+
+        Collection<String> getEntryNames() {
+            return Collections.unmodifiableCollection(mEntries.keySet());
+        }
+
+        Collection<AccessControlProfileId> getAccessControlProfileIds(String name) {
+            EntryData value = mEntries.get(name);
+            if (value != null) {
+                return value.mAccessControlProfileIds;
+            }
+            return null;
+        }
+
+        byte[] getEntryValue(String name) {
+            EntryData value = mEntries.get(name);
+            if (value != null) {
+                return value.mValue;
+            }
+            return null;
+        }
+    }
+
+    private static class EntryData {
+        byte[] mValue;
+        Collection<AccessControlProfileId> mAccessControlProfileIds;
+
+        EntryData(byte[] value, Collection<AccessControlProfileId> accessControlProfileIds) {
+            this.mValue = value;
+            this.mAccessControlProfileIds = accessControlProfileIds;
+        }
+    }
+
+    /**
+     * A builder for {@link PersonalizationData}.
+     */
+    public static final class Builder {
+        private PersonalizationData mData;
+
+        /**
+         * Creates a new builder for a given namespace.
+         */
+        public Builder() {
+            this.mData = new PersonalizationData();
+        }
+
+        /**
+         * Adds a new entry to the builder.
+         *
+         * @param namespace               The namespace to use, e.g. {@code org.iso.18013-5.2019}.
+         * @param name                    The name of the entry, e.g. {@code height}.
+         * @param accessControlProfileIds A set of access control profiles to use.
+         * @param value                   The value to add, in CBOR encoding.
+         * @return The builder.
+         */
+        public @NonNull Builder setEntry(@NonNull String namespace, @NonNull String name,
+                @NonNull Collection<AccessControlProfileId> accessControlProfileIds,
+                @NonNull byte[] value) {
+            NamespaceData namespaceData = mData.mNamespaces.get(namespace);
+            if (namespaceData == null) {
+                namespaceData = new NamespaceData(namespace);
+                mData.mNamespaces.put(namespace, namespaceData);
+            }
+            // TODO: validate/verify that value is proper CBOR.
+            namespaceData.mEntries.put(name, new EntryData(value, accessControlProfileIds));
+            return this;
+        }
+
+        /**
+         * Adds a new access control profile to the builder.
+         *
+         * @param profile The access control profile.
+         * @return The builder.
+         */
+        public @NonNull Builder addAccessControlProfile(@NonNull AccessControlProfile profile) {
+            mData.mProfiles.add(profile);
+            return this;
+        }
+
+        /**
+         * Creates a new {@link PersonalizationData} with all the entries added to the builder.
+         *
+         * @return A new {@link PersonalizationData} instance.
+         */
+        public @NonNull PersonalizationData build() {
+            return mData;
+        }
+    }
+
+}
diff --git a/identity/java/android/security/identity/ResultData.java b/identity/java/android/security/identity/ResultData.java
new file mode 100644
index 0000000..0982c8a
--- /dev/null
+++ b/identity/java/android/security/identity/ResultData.java
@@ -0,0 +1,224 @@
+/*
+ * 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.security.identity;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.util.Collection;
+
+/**
+ * An object that contains the result of retrieving data from a credential. This is used to return
+ * data requested from a {@link IdentityCredential}.
+ */
+public abstract class ResultData {
+
+    /** Value was successfully retrieved. */
+    public static final int STATUS_OK = 0;
+
+    /** Requested entry does not exist. */
+    public static final int STATUS_NO_SUCH_ENTRY = 1;
+
+    /** Requested entry was not requested. */
+    public static final int STATUS_NOT_REQUESTED = 2;
+
+    /** Requested entry wasn't in the request message. */
+    public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3;
+
+    /** The requested entry was not retrieved because user authentication wasn't performed. */
+    public static final int STATUS_USER_AUTHENTICATION_FAILED = 4;
+
+    /** The requested entry was not retrieved because reader authentication wasn't performed. */
+    public static final int STATUS_READER_AUTHENTICATION_FAILED = 5;
+
+    /**
+     * The requested entry was not retrieved because it was configured without any access
+     * control profile.
+     */
+    public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
+
+    /**
+     * @hide
+     */
+    protected ResultData() {}
+
+    /**
+     * Returns a CBOR structure containing the retrieved data.
+     *
+     * <p>This structure - along with the session transcript - may be cryptographically
+     * authenticated to prove to the reader that the data is from a trusted credential and
+     * {@link #getMessageAuthenticationCode()} can be used to get a MAC.
+     *
+     * <p>The CBOR structure which is cryptographically authenticated is the
+     * {@code DeviceAuthentication} structure according to the following
+     * <a href="https://tools.ietf.org/html/draft-ietf-cbor-cddl-06">CDDL</a> schema:
+     *
+     * <pre>
+     *   DeviceAuthentication = [
+     *     "DeviceAuthentication",
+     *     SessionTranscript,
+     *     DocType,
+     *     DeviceNameSpacesBytes
+     *   ]
+     *
+     *   DocType = tstr
+     *
+     *   SessionTranscript = [
+     *     DeviceEngagementBytes,
+     *     EReaderKeyBytes
+     *   ]
+     *
+     *   DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
+     *   EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
+     *
+     *   DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
+     * </pre>
+     *
+     * where
+     *
+     * <pre>
+     *   DeviceNameSpaces = {
+     *     * NameSpace => DeviceSignedItems
+     *   }
+     *
+     *   DeviceSignedItems = {
+     *     + DataItemName => DataItemValue
+     *   }
+     *
+     *   NameSpace = tstr
+     *   DataItemName = tstr
+     *   DataItemValue = any
+     * </pre>
+     *
+     * <p>The returned data is the binary encoding of the {@code DeviceNameSpaces} structure
+     * as defined above.
+     *
+     * @return The bytes of the {@code DeviceNameSpaces} CBOR structure.
+     */
+    public abstract @NonNull byte[] getAuthenticatedData();
+
+    /**
+     * Returns a message authentication code over the data returned by
+     * {@link #getAuthenticatedData}, to prove to the reader that the data is from a trusted
+     * credential.
+     *
+     * <p>The MAC proves to the reader that the data is from a trusted credential. This code is
+     * produced by using the key agreement and key derivation function from the ciphersuite
+     * with the authentication private key and the reader ephemeral public key to compute a
+     * shared message authentication code (MAC) key, then using the MAC function from the
+     * ciphersuite to compute a MAC of the authenticated data.
+     *
+     * <p>If the {@code sessionTranscript} parameter passed to
+     * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])} was {@code null}
+     * or the reader ephmeral public key was never set using
+     * {@link IdentityCredential#setReaderEphemeralPublicKey(PublicKey)}, no message
+     * authencation code will be produced and this method will return {@code null}.
+     *
+     * @return A COSE_Mac0 structure with the message authentication code as described above
+     *         or {@code null} if the conditions specified above are not met.
+     */
+    public abstract @Nullable byte[] getMessageAuthenticationCode();
+
+    /**
+     * Returns the static authentication data associated with the dynamic authentication
+     * key used to sign or MAC the data returned by {@link #getAuthenticatedData()}.
+     *
+     * @return The static authentication data associated with dynamic authentication key used to
+     * MAC the data.
+     */
+    public abstract @NonNull byte[] getStaticAuthenticationData();
+
+    /**
+     * Gets the names of namespaces with retrieved entries.
+     *
+     * @return collection of name of namespaces containing retrieved entries. May be empty if no
+     *     data was retrieved.
+     */
+    public abstract @NonNull Collection<String> getNamespaceNames();
+
+    /**
+     * Get the names of all entries.
+     *
+     * This includes the name of entries that wasn't successfully retrieved.
+     *
+     * @param namespaceName the namespace name to get entries for.
+     * @return A collection of names or {@code null} if there are no entries for the given
+     *     namespace.
+     */
+    public abstract @Nullable Collection<String> getEntryNames(@NonNull String namespaceName);
+
+    /**
+     * Get the names of all entries that was successfully retrieved.
+     *
+     * This only return entries for which {@link #getStatus(String, String)} will return
+     * {@link #STATUS_OK}.
+     *
+     * @param namespaceName the namespace name to get entries for.
+     * @return A collection of names or {@code null} if there are no entries for the given
+     *     namespace.
+     */
+    public abstract @Nullable Collection<String> getRetrievedEntryNames(
+            @NonNull String namespaceName);
+
+    /**
+     * Gets the status of an entry.
+     *
+     * This returns {@link #STATUS_OK} if the value was retrieved, {@link #STATUS_NO_SUCH_ENTRY}
+     * if the given entry wasn't retrieved, {@link #STATUS_NOT_REQUESTED} if it wasn't requested,
+     * {@link #STATUS_NOT_IN_REQUEST_MESSAGE} if the request message was set but the entry wasn't
+     * present in the request message,
+     * {@link #STATUS_USER_AUTHENTICATION_FAILED} if the value
+     * wasn't retrieved because the necessary user authentication wasn't performed,
+     * {@link #STATUS_READER_AUTHENTICATION_FAILED} if the supplied reader certificate chain
+     * didn't match the set of certificates the entry was provisioned with, or
+     * {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was configured without any
+     * access control profiles.
+     *
+     * @param namespaceName the namespace name of the entry.
+     * @param name the name of the entry to get the value for.
+     * @return the status indicating whether the value was retrieved and if not, why.
+     */
+    @Status
+    public abstract int getStatus(@NonNull String namespaceName, @NonNull String name);
+
+    /**
+     * Gets the raw CBOR data for the value of an entry.
+     *
+     * This should only be called on an entry for which the {@link #getStatus(String, String)}
+     * method returns {@link #STATUS_OK}.
+     *
+     * @param namespaceName the namespace name of the entry.
+     * @param name the name of the entry to get the value for.
+     * @return the raw CBOR data or {@code null} if no entry with the given name exists.
+     */
+    public abstract @Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name);
+
+    /**
+     * The type of the entry status.
+     * @hide
+     */
+    @Retention(SOURCE)
+    @IntDef({STATUS_OK, STATUS_NO_SUCH_ENTRY, STATUS_NOT_REQUESTED, STATUS_NOT_IN_REQUEST_MESSAGE,
+                        STATUS_USER_AUTHENTICATION_FAILED, STATUS_READER_AUTHENTICATION_FAILED,
+                        STATUS_NO_ACCESS_CONTROL_PROFILES})
+    public @interface Status {
+    }
+}
diff --git a/identity/java/android/security/identity/SessionTranscriptMismatchException.java b/identity/java/android/security/identity/SessionTranscriptMismatchException.java
new file mode 100644
index 0000000..8c24060
--- /dev/null
+++ b/identity/java/android/security/identity/SessionTranscriptMismatchException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown when trying use multiple different session transcripts in the same presentation session.
+ */
+public class SessionTranscriptMismatchException extends IdentityCredentialException {
+
+    /**
+     * Constructs a new {@link SessionTranscriptMismatchException} exception.
+     *
+     * @param message the detail message.
+     */
+    public SessionTranscriptMismatchException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link SessionTranscriptMismatchException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public SessionTranscriptMismatchException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/UnknownAuthenticationKeyException.java b/identity/java/android/security/identity/UnknownAuthenticationKeyException.java
new file mode 100644
index 0000000..f454b2c
--- /dev/null
+++ b/identity/java/android/security/identity/UnknownAuthenticationKeyException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown if trying to certify an unknown dynamic authentication key.
+ */
+public class UnknownAuthenticationKeyException extends IdentityCredentialException {
+    /**
+     * Constructs a new {@link UnknownAuthenticationKeyException} exception.
+     *
+     * @param message the detail message.
+     */
+    public UnknownAuthenticationKeyException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@link UnknownAuthenticationKeyException} exception.
+     *
+     * @param message the detail message.
+     * @param cause   the cause.
+     */
+    public UnknownAuthenticationKeyException(@NonNull String message, @NonNull Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/identity/java/android/security/identity/Util.java b/identity/java/android/security/identity/Util.java
new file mode 100644
index 0000000..6eefeb8
--- /dev/null
+++ b/identity/java/android/security/identity/Util.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECPoint;
+import java.util.Collection;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+class Util {
+    private static final String TAG = "Util";
+
+    static int[] integerCollectionToArray(Collection<Integer> collection) {
+        int[] result = new int[collection.size()];
+        int n = 0;
+        for (int item : collection) {
+            result[n++] = item;
+        }
+        return result;
+    }
+
+    static byte[] stripLeadingZeroes(byte[] value) {
+        int n = 0;
+        while (n < value.length && value[n] == 0) {
+            n++;
+        }
+        int newLen = value.length - n;
+        byte[] ret = new byte[newLen];
+        int m = 0;
+        while (n < value.length) {
+            ret[m++] = value[n++];
+        }
+        return ret;
+    }
+
+    static byte[] publicKeyEncodeUncompressedForm(PublicKey publicKey) {
+        ECPoint w = ((ECPublicKey) publicKey).getW();
+        // X and Y are always positive so for interop we remove any leading zeroes
+        // inserted by the BigInteger encoder.
+        byte[] x = stripLeadingZeroes(w.getAffineX().toByteArray());
+        byte[] y = stripLeadingZeroes(w.getAffineY().toByteArray());
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            baos.write(0x04);
+            baos.write(x);
+            baos.write(y);
+            return baos.toByteArray();
+        } catch (IOException e) {
+            throw new RuntimeException("Unexpected IOException", e);
+        }
+    }
+
+    /**
+     * Computes an HKDF.
+     *
+     * This is based on https://github.com/google/tink/blob/master/java/src/main/java/com/google
+     * /crypto/tink/subtle/Hkdf.java
+     * which is also Copyright (c) Google and also licensed under the Apache 2 license.
+     *
+     * @param macAlgorithm the MAC algorithm used for computing the Hkdf. I.e., "HMACSHA1" or
+     *                     "HMACSHA256".
+     * @param ikm          the input keying material.
+     * @param salt         optional salt. A possibly non-secret random value. If no salt is
+     *                     provided (i.e. if
+     *                     salt has length 0) then an array of 0s of the same size as the hash
+     *                     digest is used as salt.
+     * @param info         optional context and application specific information.
+     * @param size         The length of the generated pseudorandom string in bytes. The maximal
+     *                     size is
+     *                     255.DigestSize, where DigestSize is the size of the underlying HMAC.
+     * @return size pseudorandom bytes.
+     */
+    static byte[] computeHkdf(
+            String macAlgorithm, final byte[] ikm, final byte[] salt, final byte[] info, int size) {
+        Mac mac = null;
+        try {
+            mac = Mac.getInstance(macAlgorithm);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("No such algorithm: " + macAlgorithm, e);
+        }
+        if (size > 255 * mac.getMacLength()) {
+            throw new RuntimeException("size too large");
+        }
+        try {
+            if (salt == null || salt.length == 0) {
+                // According to RFC 5869, Section 2.2 the salt is optional. If no salt is provided
+                // then HKDF uses a salt that is an array of zeros of the same length as the hash
+                // digest.
+                mac.init(new SecretKeySpec(new byte[mac.getMacLength()], macAlgorithm));
+            } else {
+                mac.init(new SecretKeySpec(salt, macAlgorithm));
+            }
+            byte[] prk = mac.doFinal(ikm);
+            byte[] result = new byte[size];
+            int ctr = 1;
+            int pos = 0;
+            mac.init(new SecretKeySpec(prk, macAlgorithm));
+            byte[] digest = new byte[0];
+            while (true) {
+                mac.update(digest);
+                mac.update(info);
+                mac.update((byte) ctr);
+                digest = mac.doFinal();
+                if (pos + digest.length < size) {
+                    System.arraycopy(digest, 0, result, pos, digest.length);
+                    pos += digest.length;
+                    ctr++;
+                } else {
+                    System.arraycopy(digest, 0, result, pos, size - pos);
+                    break;
+                }
+            }
+            return result;
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("Error MACing", e);
+        }
+    }
+
+}
diff --git a/identity/java/android/security/identity/WritableIdentityCredential.java b/identity/java/android/security/identity/WritableIdentityCredential.java
new file mode 100644
index 0000000..5f575b9
--- /dev/null
+++ b/identity/java/android/security/identity/WritableIdentityCredential.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.identity;
+
+import android.annotation.NonNull;
+
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+
+/**
+ * Class used to personalize a new identity credential.
+ *
+ * <p>Credentials cannot be updated or modified after creation; any changes require deletion and
+ * re-creation.
+ *
+ * Use {@link IdentityCredentialStore#createCredential(String, String)} to create a new credential.
+ */
+public abstract class WritableIdentityCredential {
+    /**
+     * Generates and returns an X.509 certificate chain for the CredentialKey which identifies this
+     * credential to the issuing authority. The certificate contains an
+     * <a href="https://source.android.com/security/keystore/attestation">Android Keystore</a>
+     * attestation extension which describes the key and the security hardware in which it lives.
+     *
+     * <p>Additionally, the attestation extension will contain the tag TODO_IC_KEY which indicates
+     * it is an Identity Credential key (which can only sign/MAC very specific messages) and not
+     * an Android Keystore key (which can be used to sign/MAC anything).
+     *
+     * <p>The issuer <b>MUST</b> carefully examine this certificate chain including (but not
+     * limited to) checking that the root certificate is well-known, the tag TODO_IC_KEY is
+     * present, the passed in challenge is present, the device has verified boot enabled, that each
+     * certificate in the chain is signed by its successor, that none of the certificates have been
+     * revoked and so on.
+     *
+     * <p>It is not strictly necessary to use this method to provision a credential if the issuing
+     * authority doesn't care about the nature of the security hardware. If called, however, this
+     * method must be called before {@link #personalize(PersonalizationData)}.
+     *
+     * @param challenge is a byte array whose contents should be unique, fresh and provided by
+     *                  the issuing authority. The value provided is embedded in the attestation
+     *                  extension and enables the issuing authority to verify that the attestation
+     *                  certificate is fresh.
+     * @return the X.509 certificate for this credential's CredentialKey.
+     */
+    public abstract @NonNull Collection<X509Certificate> getCredentialKeyCertificateChain(
+            @NonNull byte[] challenge);
+
+    /**
+     * Stores all of the data in the credential, with the specified access control profiles.
+     *
+     * <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey with payload
+     * set to {@code ProofOfProvisioning} as defined below.
+     *
+     * <pre>
+     *     ProofOfProvisioning = [
+     *          "ProofOfProvisioning",        ; tstr
+     *          tstr,                         ; DocType
+     *          [ * AccessControlProfile ],
+     *          ProvisionedData,
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *      ]
+     *
+     *      AccessControlProfile = {
+     *          "id": uint,
+     *          ? "readerCertificate" : bstr,
+     *          ? (
+     *               "userAuthenticationRequired" : bool,
+     *               "timeoutMillis" : uint,
+     *          )
+     *      }
+     *
+     *      ProvisionedData = {
+     *          * Namespace =&gt; [ + Entry ]
+     *      },
+     *
+     *      Namespace = tstr
+     *
+     *      Entry = {
+     *          "name" : tstr,
+     *          "value" : any,
+     *          "accessControlProfiles" : [ * uint ],
+     *      }
+     * </pre>
+     *
+     * <p>This data structure provides a guarantee to the issuer about the data which may be
+     * returned in the CBOR returned by
+     * {@link ResultData#getAuthenticatedData()} during a credential
+     * presentation.
+     *
+     * @param personalizationData   The data to provision, including access control profiles
+     *                              and data elements and their values, grouped into namespaces.
+     * @return A COSE_Sign1 data structure, see above.
+     */
+    public abstract @NonNull byte[] personalize(
+            @NonNull PersonalizationData personalizationData);
+}
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index d6b516f..5a50245 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -18,6 +18,8 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
+// TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead.
+#include <surfacetexture/surface_texture_platform.h>
 #include "AutoBackendTextureRelease.h"
 #include "Matrix.h"
 #include "Properties.h"
@@ -34,6 +36,7 @@
 DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState)
         : mRenderState(renderState)
         , mBlend(false)
+        , mSurfaceTexture(nullptr, [](ASurfaceTexture*) {})
         , mTransform(nullptr)
         , mGLContextAttached(false)
         , mUpdateTexImage(false)
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 289f65c..c44c0d5 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -21,8 +21,7 @@
 #include <SkMatrix.h>
 #include <android/hardware_buffer.h>
 #include <cutils/compiler.h>
-// TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead.
-#include <gui/surfacetexture/surface_texture_platform.h>
+#include <android/surface_texture.h>
 
 #include <map>
 #include <memory>
@@ -37,7 +36,7 @@
 class AutoBackendTextureRelease;
 class RenderState;
 
-typedef std::unique_ptr<ASurfaceTexture> AutoTextureRelease;
+typedef std::unique_ptr<ASurfaceTexture, decltype(&ASurfaceTexture_release)> AutoTextureRelease;
 
 // Container to hold the properties a layer should be set to at the start
 // of a render pass
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 84549e8..3c402e9 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -38,7 +38,7 @@
 
 #include <SkCanvas.h>
 #include <SkImagePriv.h>
-
+#include <SkWebpEncoder.h>
 #include <SkHighContrastFilter.h>
 #include <limits>
 
@@ -471,4 +471,59 @@
     return BitmapPalette::Unknown;
 }
 
+Bitmap::CompressResult Bitmap::compress(JavaCompressFormat format, int32_t quality,
+                                        SkWStream* stream) {
+    SkBitmap skbitmap;
+    getSkBitmap(&skbitmap);
+    return compress(skbitmap, format, quality, stream);
+}
+
+Bitmap::CompressResult Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format,
+                                        int32_t quality, SkWStream* stream) {
+    SkBitmap skbitmap = bitmap;
+    if (skbitmap.colorType() == kRGBA_F16_SkColorType) {
+        // Convert to P3 before encoding. This matches
+        // SkAndroidCodec::computeOutputColorSpace for wide gamuts. Now that F16
+        // could already be P3, we still want to convert to 8888.
+        auto cs = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
+        auto info = skbitmap.info().makeColorType(kRGBA_8888_SkColorType)
+                                   .makeColorSpace(std::move(cs));
+        SkBitmap p3;
+        if (!p3.tryAllocPixels(info)) {
+            return CompressResult::AllocationFailed;
+        }
+
+        SkPixmap pm;
+        SkAssertResult(p3.peekPixels(&pm));  // should always work if tryAllocPixels() did.
+        if (!skbitmap.readPixels(pm)) {
+            return CompressResult::Error;
+        }
+        skbitmap = p3;
+    }
+
+    SkEncodedImageFormat fm;
+    switch (format) {
+        case JavaCompressFormat::Jpeg:
+            fm = SkEncodedImageFormat::kJPEG;
+            break;
+        case JavaCompressFormat::Png:
+            fm = SkEncodedImageFormat::kPNG;
+            break;
+        case JavaCompressFormat::Webp:
+            fm = SkEncodedImageFormat::kWEBP;
+            break;
+        case JavaCompressFormat::WebpLossy:
+        case JavaCompressFormat::WebpLossless: {
+            SkWebpEncoder::Options options;
+            options.fQuality = quality;
+            options.fCompression = format == JavaCompressFormat::WebpLossy ?
+                    SkWebpEncoder::Compression::kLossy : SkWebpEncoder::Compression::kLossless;
+            return SkWebpEncoder::Encode(stream, skbitmap.pixmap(), options)
+                    ? CompressResult::Success : CompressResult::Error;
+        }
+    }
+
+    return SkEncodeImage(stream, skbitmap, fm, quality)
+            ? CompressResult::Success : CompressResult::Error;
+}
 }  // namespace android
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 1cda046..ee365af 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -27,6 +27,8 @@
 #include <android/hardware_buffer.h>
 #endif
 
+class SkWStream;
+
 namespace android {
 
 enum class PixelStorageType {
@@ -142,6 +144,26 @@
   // and places that value in size.
   static bool computeAllocationSize(size_t rowBytes, int height, size_t* size);
 
+  // These must match the int values of CompressFormat in Bitmap.java, as well as
+  // AndroidBitmapCompressFormat.
+  enum class JavaCompressFormat {
+    Jpeg = 0,
+    Png = 1,
+    Webp = 2,
+    WebpLossy = 3,
+    WebpLossless = 4,
+  };
+
+  enum class CompressResult {
+    Success,
+    AllocationFailed,
+    Error,
+  };
+
+  CompressResult compress(JavaCompressFormat format, int32_t quality, SkWStream* stream);
+
+  static CompressResult compress(const SkBitmap& bitmap, JavaCompressFormat format,
+                                 int32_t quality, SkWStream* stream);
 private:
     static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
     static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index 4f2027d..a6c4e9d 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -30,19 +30,25 @@
     , mTargetSize(mCodec->getInfo().dimensions())
     , mDecodeSize(mTargetSize)
     , mOutColorType(mCodec->computeOutputColorType(kN32_SkColorType))
-    , mOutAlphaType(mCodec->getInfo().isOpaque() ?
-                    kOpaque_SkAlphaType : kPremul_SkAlphaType)
+    , mUnpremultipliedRequired(false)
     , mOutColorSpace(mCodec->getInfo().refColorSpace())
     , mSampleSize(1)
 {
 }
 
+SkAlphaType ImageDecoder::getOutAlphaType() const {
+    // While an SkBitmap may want to use kOpaque_SkAlphaType for a performance
+    // optimization, this class just outputs raw pixels. Using either
+    // premultiplication choice has no effect on decoding an opaque encoded image.
+    return mUnpremultipliedRequired ? kUnpremul_SkAlphaType : kPremul_SkAlphaType;
+}
+
 bool ImageDecoder::setTargetSize(int width, int height) {
     if (width <= 0 || height <= 0) {
         return false;
     }
 
-    auto info = SkImageInfo::Make(width, height, mOutColorType, mOutAlphaType);
+    auto info = SkImageInfo::Make(width, height, mOutColorType, getOutAlphaType());
     size_t rowBytes = info.minRowBytes();
     if (rowBytes == 0) {
         // This would have overflowed.
@@ -63,7 +69,7 @@
     SkISize targetSize = { width, height }, decodeSize = targetSize;
     int sampleSize = mCodec->computeSampleSize(&decodeSize);
 
-    if (decodeSize != targetSize && mOutAlphaType == kUnpremul_SkAlphaType
+    if (decodeSize != targetSize && mUnpremultipliedRequired
             && !mCodec->getInfo().isOpaque()) {
         return false;
     }
@@ -119,29 +125,11 @@
     return true;
 }
 
-bool ImageDecoder::setOutAlphaType(SkAlphaType alpha) {
-    switch (alpha) {
-        case kOpaque_SkAlphaType:
-            return opaque();
-        case kPremul_SkAlphaType:
-            if (opaque()) {
-                // Opaque can be treated as premul.
-                return true;
-            }
-            break;
-        case kUnpremul_SkAlphaType:
-            if (opaque()) {
-                // Opaque can be treated as unpremul.
-                return true;
-            }
-            if (mDecodeSize != mTargetSize) {
-                return false;
-            }
-            break;
-        default:
-            return false;
+bool ImageDecoder::setUnpremultipliedRequired(bool required) {
+    if (required && !opaque() && mDecodeSize != mTargetSize) {
+        return false;
     }
-    mOutAlphaType = alpha;
+    mUnpremultipliedRequired = required;
     return true;
 }
 
@@ -151,11 +139,11 @@
 
 SkImageInfo ImageDecoder::getOutputInfo() const {
     SkISize size = mCropRect ? mCropRect->size() : mTargetSize;
-    return SkImageInfo::Make(size, mOutColorType, mOutAlphaType, mOutColorSpace);
+    return SkImageInfo::Make(size, mOutColorType, getOutAlphaType(), mOutColorSpace);
 }
 
 bool ImageDecoder::opaque() const {
-    return mOutAlphaType == kOpaque_SkAlphaType;
+    return mCodec->getInfo().alphaType() == kOpaque_SkAlphaType;
 }
 
 bool ImageDecoder::gray() const {
@@ -165,7 +153,8 @@
 SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) {
     void* decodePixels = pixels;
     size_t decodeRowBytes = rowBytes;
-    auto decodeInfo = SkImageInfo::Make(mDecodeSize, mOutColorType, mOutAlphaType, mOutColorSpace);
+    auto decodeInfo = SkImageInfo::Make(mDecodeSize, mOutColorType, getOutAlphaType(),
+                                        mOutColorSpace);
     // Used if we need a temporary before scaling or subsetting.
     // FIXME: Use scanline decoding on only a couple lines to save memory. b/70709380.
     SkBitmap tmp;
diff --git a/libs/hwui/hwui/ImageDecoder.h b/libs/hwui/hwui/ImageDecoder.h
index b956f4a..96f97e5 100644
--- a/libs/hwui/hwui/ImageDecoder.h
+++ b/libs/hwui/hwui/ImageDecoder.h
@@ -41,14 +41,12 @@
 
     bool setOutColorType(SkColorType outColorType);
 
-    bool setOutAlphaType(SkAlphaType outAlphaType);
+    bool setUnpremultipliedRequired(bool unpremultipliedRequired);
 
     void setOutColorSpace(sk_sp<SkColorSpace> cs);
 
     // The size is the final size after scaling and cropping.
     SkImageInfo getOutputInfo() const;
-    SkColorType getOutColorType() const { return mOutColorType; }
-    SkAlphaType getOutAlphaType() const { return mOutAlphaType; }
 
     bool opaque() const;
     bool gray() const;
@@ -59,13 +57,15 @@
     SkISize mTargetSize;
     SkISize mDecodeSize;
     SkColorType mOutColorType;
-    SkAlphaType mOutAlphaType;
+    bool mUnpremultipliedRequired;
     sk_sp<SkColorSpace> mOutColorSpace;
     int mSampleSize;
     std::optional<SkIRect> mCropRect;
 
     ImageDecoder(const ImageDecoder&) = delete;
     ImageDecoder& operator=(const ImageDecoder&) = delete;
+
+    SkAlphaType getOutAlphaType() const;
 };
 
 } // namespace android
diff --git a/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp b/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp
index 2c78b02..551bdc6 100644
--- a/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp
+++ b/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp
@@ -24,8 +24,8 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-// When purgeable is INVALID_TIME it won't be logged at all.
-#define INVALID_TIME -1
+// When purgeable is INVALID_MEMORY_SIZE it won't be logged at all.
+#define INVALID_MEMORY_SIZE -1
 
 /**
  * Skia invokes the following SkTraceMemoryDump functions:
@@ -42,10 +42,10 @@
  * "GPU Memory" category.
  */
 static std::unordered_map<const char*, const char*> sResourceMap = {
-        {"malloc", "Graphics CPU Memory"},          // taken from setMemoryBacking(backingType)
-        {"gl_texture", "Graphics Texture Memory"},  // taken from setMemoryBacking(backingType)
+        {"malloc", "HWUI CPU Memory"},          // taken from setMemoryBacking(backingType)
+        {"gl_texture", "HWUI Texture Memory"},  // taken from setMemoryBacking(backingType)
         {"Texture",
-         "Graphics Texture Memory"},  // taken from dumpStringValue(value, valueName="type")
+         "HWUI Texture Memory"},  // taken from dumpStringValue(value, valueName="type")
         // Uncomment categories below to split "GPU Memory" into more brackets for debugging.
         /*{"vk_buffer", "vk_buffer"},
         {"gl_renderbuffer", "gl_renderbuffer"},
@@ -105,10 +105,10 @@
         // Once a category is observed in at least one frame, it is always reported in subsequent
         // frames (even if it is 0). Not logging a category to ATRACE would mean its value has not
         // changed since the previous frame, which is not what we want.
-        it.second.time = 0;
-        // If purgeableTime is INVALID_TIME, then logTraces won't log it at all.
-        if (it.second.purgeableTime != INVALID_TIME) {
-            it.second.purgeableTime = 0;
+        it.second.memory = 0;
+        // If purgeableMemory is INVALID_MEMORY_SIZE, then logTraces won't log it at all.
+        if (it.second.purgeableMemory != INVALID_MEMORY_SIZE) {
+            it.second.purgeableMemory = 0;
         }
     }
 }
@@ -119,12 +119,15 @@
 void ATraceMemoryDump::logTraces() {
     // Accumulate data from last dumpName
     recordAndResetCountersIfNeeded("");
+    uint64_t hwui_all_frame_memory = 0;
     for (auto& it : mCurrentValues) {
-        ATRACE_INT64(it.first.c_str(), it.second.time);
-        if (it.second.purgeableTime != INVALID_TIME) {
-            ATRACE_INT64((std::string("Purgeable ") + it.first).c_str(), it.second.purgeableTime);
+        hwui_all_frame_memory += it.second.memory;
+        ATRACE_INT64(it.first.c_str(), it.second.memory);
+        if (it.second.purgeableMemory != INVALID_MEMORY_SIZE) {
+            ATRACE_INT64((std::string("Purgeable ") + it.first).c_str(), it.second.purgeableMemory);
         }
     }
+    ATRACE_INT64("HWUI All Memory", hwui_all_frame_memory);
 }
 
 /**
@@ -145,12 +148,12 @@
         // A new dumpName observed -> store the data already collected.
         auto memoryCounter = mCurrentValues.find(mCategory);
         if (memoryCounter != mCurrentValues.end()) {
-            memoryCounter->second.time += mLastDumpValue;
-            if (mLastPurgeableDumpValue != INVALID_TIME) {
-                if (memoryCounter->second.purgeableTime == INVALID_TIME) {
-                    memoryCounter->second.purgeableTime = mLastPurgeableDumpValue;
+            memoryCounter->second.memory += mLastDumpValue;
+            if (mLastPurgeableDumpValue != INVALID_MEMORY_SIZE) {
+                if (memoryCounter->second.purgeableMemory == INVALID_MEMORY_SIZE) {
+                    memoryCounter->second.purgeableMemory = mLastPurgeableDumpValue;
                 } else {
-                    memoryCounter->second.purgeableTime += mLastPurgeableDumpValue;
+                    memoryCounter->second.purgeableMemory += mLastPurgeableDumpValue;
                 }
             }
         } else {
@@ -164,10 +167,10 @@
 
 void ATraceMemoryDump::resetCurrentCounter(const char* dumpName) {
     mLastDumpValue = 0;
-    mLastPurgeableDumpValue = INVALID_TIME;
+    mLastPurgeableDumpValue = INVALID_MEMORY_SIZE;
     mLastDumpName = dumpName;
     // Categories not listed in sResourceMap are reported as "GPU memory"
-    mCategory = "GPU Memory";
+    mCategory = "HWUI GPU Memory";
 }
 
 } /* namespace skiapipeline */
diff --git a/libs/hwui/pipeline/skia/ATraceMemoryDump.h b/libs/hwui/pipeline/skia/ATraceMemoryDump.h
index aa5c401..4592711 100644
--- a/libs/hwui/pipeline/skia/ATraceMemoryDump.h
+++ b/libs/hwui/pipeline/skia/ATraceMemoryDump.h
@@ -62,8 +62,8 @@
     std::string mCategory;
 
     struct TraceValue {
-        uint64_t time;
-        uint64_t purgeableTime;
+        uint64_t memory;
+        uint64_t purgeableMemory;
     };
 
     // keys are define in sResourceMap
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 35a885f..b940cff 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -458,9 +458,15 @@
                                    const SkMatrix& preTransform) {
     SkAutoCanvasRestore saver(canvas, true);
     auto clipRestriction = preTransform.mapRect(clip).roundOut();
-    canvas->androidFramework_setDeviceClipRestriction(clipRestriction);
-    canvas->drawAnnotation(SkRect::Make(clipRestriction), "AndroidDeviceClipRestriction",
-        nullptr);
+    if (CC_UNLIKELY(mCaptureMode == CaptureMode::SingleFrameSKP
+         || mCaptureMode == CaptureMode::MultiFrameSKP)) {
+        canvas->drawAnnotation(SkRect::Make(clipRestriction), "AndroidDeviceClipRestriction",
+            nullptr);
+    } else {
+        // clip drawing to dirty region only when not recording SKP files (which should contain all
+        // draw ops on every frame)
+        canvas->androidFramework_setDeviceClipRestriction(clipRestriction);
+    }
     canvas->concat(preTransform);
 
     // STOPSHIP: Revert, temporary workaround to clear always F16 frame buffer for b/74976293
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 0ced68ef..4dbc79b 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -213,6 +213,36 @@
 
     private final static String TAG = "android.media.AudioTrack";
 
+    /** @hide */
+    @IntDef({
+        ENCAPSULATION_MODE_NONE,
+        ENCAPSULATION_MODE_ELEMENTARY_STREAM,
+        ENCAPSULATION_MODE_HANDLE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapsulationMode {}
+
+    // Important: The ENCAPSULATION_MODE values must be kept in sync with native header files.
+    /**
+     * This mode indicates no metadata encapsulation,
+     * which is the default mode for sending audio data
+     * through {@code AudioTrack}.
+     */
+    public static final int ENCAPSULATION_MODE_NONE = 0;
+    /**
+     * This mode indicates metadata encapsulation with an elementary stream payload.
+     * Both compressed and PCM format is allowed.
+     *
+     * TODO(b/147778408) Link: See the Android developers guide for more information.
+     */
+    public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1;
+    /**
+     * This mode indicates metadata encapsulation with a handle payload.
+     * The handle is a 64 bit long, provided by the Tuner API.
+     *
+     * TODO(b/147778408) Link: Fill in Tuner API to obtain the handle.
+     */
+    public static final int ENCAPSULATION_MODE_HANDLE = 2;
 
     /** @hide */
     @IntDef({
@@ -592,11 +622,13 @@
     public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
             int mode, int sessionId)
                     throws IllegalArgumentException {
-        this(attributes, format, bufferSizeInBytes, mode, sessionId, false /*offload*/);
+        this(attributes, format, bufferSizeInBytes, mode, sessionId, false /*offload*/,
+                ENCAPSULATION_MODE_NONE, null /* tunerConfiguration */);
     }
 
     private AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
-            int mode, int sessionId, boolean offload)
+            int mode, int sessionId, boolean offload, int encapsulationMode,
+            @Nullable TunerConfiguration tunerConfiguration)
                     throws IllegalArgumentException {
         super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_AUDIOTRACK);
         // mState already == STATE_UNINITIALIZED
@@ -663,7 +695,7 @@
         int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
                 sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
                 mNativeBufferSizeInBytes, mDataLoadMode, session, 0 /*nativeTrackInJavaObj*/,
-                offload);
+                offload, encapsulationMode, tunerConfiguration);
         if (initResult != SUCCESS) {
             loge("Error code "+initResult+" when initializing AudioTrack.");
             return; // with mState == STATE_UNINITIALIZED
@@ -672,6 +704,8 @@
         mSampleRate = sampleRate[0];
         mSessionId = session[0];
 
+        // TODO: consider caching encapsulationMode and tunerConfiguration in the Java object.
+
         if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) != 0) {
             int frameSizeInBytes;
             if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
@@ -745,7 +779,9 @@
                     0 /*mDataLoadMode - NA*/,
                     session,
                     nativeTrackInJavaObj,
-                    false /*offload*/);
+                    false /*offload*/,
+                    ENCAPSULATION_MODE_NONE,
+                    null /* tunerConfiguration */);
             if (initResult != SUCCESS) {
                 loge("Error code "+initResult+" when initializing AudioTrack.");
                 return; // with mState == STATE_UNINITIALIZED
@@ -758,6 +794,99 @@
     }
 
     /**
+     * TunerConfiguration is used to convey tuner information
+     * from the android.media.tv.Tuner API to AudioTrack construction.
+     *
+     * Use the Builder to construct the TunerConfiguration object,
+     * which is then used by the {@link AudioTrack.Builder} to create an AudioTrack.
+     */
+    public static class TunerConfiguration {
+        private final int mContentId;
+        private final int mSyncId;
+
+        private TunerConfiguration(int contentId, int syncId) {
+            mContentId = contentId;
+            mSyncId = syncId;
+        }
+
+        /**
+         * Returns the contentId.
+         */
+        public int getContentId() {
+            return mContentId;
+        }
+
+        /**
+         * Returns the syncId.
+         */
+        public int getSyncId() {
+            return mSyncId;
+        }
+
+        /**
+         * Builder class for {@link AudioTrack.TunerConfiguration} objects.
+         */
+        public static class Builder {
+            private int mContentId;
+            private int mSyncId;
+
+            /**
+             * Sets the contentId from the Tuner filter.
+             *
+             * @param contentId selects the audio stream to use.
+             *     See android.media.tv.tuner.filter.Filter#getId().
+             *     This is always a positive number.
+             *     TODO(b/147778408) Link to tuner filter doc when unhidden.
+             * @return the same Builder instance.
+             */
+            public @NonNull Builder setContentId(@IntRange(from = 1) int contentId) {
+                if (contentId < 1) {
+                    throw new IllegalArgumentException(
+                            "contentId " + contentId + " must be positive");
+                }
+                mContentId = contentId;
+                return this;
+            }
+
+            /**
+             * Sets the syncId from the Tuner filter.
+             *
+             * @param syncId selects the clock to use for synchronization
+             *     of audio with other streams such as video.
+             *     See android.media.tv.tuner.Tuner#getAvSyncHwId().
+             *     This is always a positive number.
+             *     TODO(b/147778408) Link to tuner filter doc when unhidden.
+             * @return the same Builder instance.
+             */
+            public @NonNull Builder setSyncId(@IntRange(from = 1) int syncId) {
+                if (syncId < 1) {
+                    throw new IllegalArgumentException("syncId " + syncId + " must be positive");
+                }
+                mSyncId = syncId;
+                return this;
+            }
+
+            /**
+             * Builds a {@link AudioTrack.TunerConfiguration} instance initialized with
+             * the parameters set on this {@code Builder}.
+             *
+             * @return a new successfully initialized {@link AudioTrack.TunerConfiguration}.
+             * @throws UnsupportedOperationException if the parameters set on the
+             *     {@code Builder} are incompatible.
+             */
+            public @NonNull TunerConfiguration build() {
+                if (mContentId < 1 || mSyncId < 1) {
+                    throw new UnsupportedOperationException(
+                            "contentId " + mContentId
+                            + " syncId " + mSyncId
+                            + " must be set");
+                }
+                return new TunerConfiguration(mContentId, mSyncId);
+            }
+        }
+    }
+
+    /**
      * Builder class for {@link AudioTrack} objects.
      * Use this class to configure and create an <code>AudioTrack</code> instance. By setting audio
      * attributes and audio format parameters, you indicate which of those vary from the default
@@ -799,10 +928,12 @@
         private AudioAttributes mAttributes;
         private AudioFormat mFormat;
         private int mBufferSizeInBytes;
+        private int mEncapsulationMode = ENCAPSULATION_MODE_NONE;
         private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
         private int mMode = MODE_STREAM;
         private int mPerformanceMode = PERFORMANCE_MODE_NONE;
         private boolean mOffload = false;
+        private TunerConfiguration mTunerConfiguration;
 
         /**
          * Constructs a new Builder with the default values as described above.
@@ -869,6 +1000,34 @@
         }
 
         /**
+         * Sets the encapsulation mode.
+         *
+         * Encapsulation mode allows metadata to be sent together with
+         * the audio data payload in a {@code ByteBuffer}.
+         * The data format is specified in the Android developers site.
+         *
+         * TODO(b/147778408) Link to doc page.
+         *
+         * @param encapsulationMode one of {@link AudioTrack#ENCAPSULATION_MODE_NONE},
+         *        {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM},
+         *        {@link AudioTrack#ENCAPSULATION_MODE_HANDLE}.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setEncapsulationMode(@EncapsulationMode int encapsulationMode) {
+            switch (encapsulationMode) {
+                case ENCAPSULATION_MODE_NONE:
+                case ENCAPSULATION_MODE_ELEMENTARY_STREAM:
+                case ENCAPSULATION_MODE_HANDLE:
+                    mEncapsulationMode = encapsulationMode;
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Invalid encapsulation mode " + encapsulationMode);
+            }
+            return this;
+        }
+
+        /**
          * Sets the mode under which buffers of audio data are transferred from the
          * {@link AudioTrack} to the framework.
          * @param mode one of {@link AudioTrack#MODE_STREAM}, {@link AudioTrack#MODE_STATIC}.
@@ -949,6 +1108,25 @@
         }
 
         /**
+         * Sets the tuner configuration for the {@code AudioTrack}.
+         *
+         * The {@link AudioTrack.TunerConfiguration} consists of parameters obtained from
+         * the Android TV tuner API which indicate the audio content stream id and the
+         * synchronization id for the {@code AudioTrack}.
+         *
+         * @param tunerConfiguration obtained by {@link AudioTrack.TunerConfiguration.Builder}.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setTunerConfiguration(
+                @NonNull TunerConfiguration tunerConfiguration) {
+            if (tunerConfiguration == null) {
+                throw new IllegalArgumentException("tunerConfiguration is null");
+            }
+            mTunerConfiguration = tunerConfiguration;
+            return this;
+        }
+
+        /**
          * Builds an {@link AudioTrack} instance initialized with all the parameters set
          * on this <code>Builder</code>.
          * @return a new successfully initialized {@link AudioTrack} instance.
@@ -1003,6 +1181,8 @@
                 }
             }
 
+            // TODO: Check mEncapsulationMode compatibility with MODE_STATIC, etc?
+
             try {
                 // If the buffer size is not specified in streaming mode,
                 // use a single frame for the buffer size and let the
@@ -1012,7 +1192,8 @@
                             * mFormat.getBytesPerSample(mFormat.getEncoding());
                 }
                 final AudioTrack track = new AudioTrack(
-                        mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId, mOffload);
+                        mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId, mOffload,
+                        mEncapsulationMode, mTunerConfiguration);
                 if (track.getState() == STATE_UNINITIALIZED) {
                     // release is not necessary
                     throw new UnsupportedOperationException("Cannot create AudioTrack");
@@ -3595,7 +3776,7 @@
             Object /*AudioAttributes*/ attributes,
             int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
             int buffSizeInBytes, int mode, int[] sessionId, long nativeAudioTrack,
-            boolean offload);
+            boolean offload, int encapsulationMode, Object tunerConfiguration);
 
     private native final void native_finalize();
 
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index e4bab74..f898931 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -99,25 +99,21 @@
 
     /**
      * Quality level corresponding to the VGA (640 x 480) resolution.
-     * @hide
      */
     public static final int QUALITY_VGA = 9;
 
     /**
      * Quality level corresponding to 4k-DCI (4096 x 2160) resolution.
-     * @hide
      */
     public static final int QUALITY_4KDCI = 10;
 
     /**
      * Quality level corresponding to QHD (2560 x 1440) resolution
-     * @hide
      */
     public static final int QUALITY_QHD = 11;
 
     /**
      * Quality level corresponding to 2K (2048 x 1080) resolution
-     * @hide
      */
     public static final int QUALITY_2K = 12;
 
@@ -172,25 +168,21 @@
 
     /**
      * Time lapse quality level corresponding to the VGA (640 x 480) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_VGA = 1009;
 
     /**
      * Time lapse quality level corresponding to the 4k-DCI (4096 x 2160) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_4KDCI = 1010;
 
     /**
      * Time lapse quality level corresponding to the QHD (2560 x 1440) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_QHD = 1011;
 
     /**
      * Time lapse quality level corresponding to the 2K (2048 x 1080) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_2K = 1012;
 
@@ -255,19 +247,16 @@
 
     /**
      * High speed ( >= 100fps) quality level corresponding to the CIF (352 x 288)
-     * @hide
      */
     public static final int QUALITY_HIGH_SPEED_CIF = 2006;
 
     /**
      * High speed ( >= 100fps) quality level corresponding to the VGA (640 x 480)
-     * @hide
      */
     public static final int QUALITY_HIGH_SPEED_VGA = 2007;
 
     /**
      * High speed ( >= 100fps) quality level corresponding to the 4K-DCI (4096 x 2160)
-     * @hide
      */
     public static final int QUALITY_HIGH_SPEED_4KDCI = 2008;
 
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 281e7c6b..dac0fba 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -46,6 +46,7 @@
 
     // Methods for media router 2
     List<MediaRoute2Info> getSystemRoutes();
+    RoutingSessionInfo getSystemSessionInfo();
     void registerClient2(IMediaRouter2Client client, String packageName);
     void unregisterClient2(IMediaRouter2Client client);
     void sendControlRequest(IMediaRouter2Client client, in MediaRoute2Info route,
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index a9e33fd..cefc9db 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -16,13 +16,15 @@
 
 package android.media;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.hardware.cas.V1_0.HidlCasPluginDescriptor;
 import android.hardware.cas.V1_0.ICas;
 import android.hardware.cas.V1_0.IMediaCasService;
-import android.hardware.cas.V1_1.ICasListener;
+import android.hardware.cas.V1_2.ICasListener;
 import android.media.MediaCasException.*;
+import android.media.tv.TvInputService.PriorityHintUseCaseType;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -34,6 +36,8 @@
 import android.util.Log;
 import android.util.Singleton;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 
 /**
@@ -100,28 +104,185 @@
     private static final String TAG = "MediaCas";
     private ICas mICas;
     private android.hardware.cas.V1_1.ICas mICasV11;
+    private android.hardware.cas.V1_2.ICas mICasV12;
     private EventListener mListener;
     private HandlerThread mHandlerThread;
     private EventHandler mEventHandler;
+    private @PriorityHintUseCaseType int mPriorityHint;
+    private String mTvInputServiceSessionId;
+
+    /**
+     * Scrambling modes used to open cas sessions.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "SCRAMBLING_MODE_",
+            value = {SCRAMBLING_MODE_RESERVED, SCRAMBLING_MODE_DVB_CSA1, SCRAMBLING_MODE_DVB_CSA2,
+            SCRAMBLING_MODE_DVB_CSA3_STANDARD,
+            SCRAMBLING_MODE_DVB_CSA3_MINIMAL, SCRAMBLING_MODE_DVB_CSA3_ENHANCE,
+            SCRAMBLING_MODE_DVB_CISSA_V1, SCRAMBLING_MODE_DVB_IDSA,
+            SCRAMBLING_MODE_MULTI2, SCRAMBLING_MODE_AES128, SCRAMBLING_MODE_AES_ECB,
+            SCRAMBLING_MODE_AES_SCTE52, SCRAMBLING_MODE_TDES_ECB, SCRAMBLING_MODE_TDES_SCTE52})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScramblingMode {}
+
+    /**
+     * DVB (Digital Video Broadcasting) reserved mode.
+     */
+    public static final int SCRAMBLING_MODE_RESERVED =
+            android.hardware.cas.V1_2.ScramblingMode.RESERVED;
+    /**
+     * DVB (Digital Video Broadcasting) Common Scrambling Algorithm (CSA) 1.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA1 =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA1;
+    /**
+     * DVB CSA 2.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA2 =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA2;
+    /**
+     * DVB CSA 3 in standard mode.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_STANDARD;
+    /**
+     * DVB CSA 3 in minimally enhanced mode.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_MINIMAL;
+    /**
+     * DVB CSA 3 in fully enhanced mode.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_ENHANCE;
+    /**
+     * DVB Common IPTV Software-oriented Scrambling Algorithm (CISSA) Version 1.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CISSA_V1 =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CISSA_V1;
+    /**
+     * ATIS-0800006 IIF Default Scrambling Algorithm (IDSA).
+     */
+    public static final int SCRAMBLING_MODE_DVB_IDSA =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_IDSA;
+    /**
+     * A symmetric key algorithm.
+     */
+    public static final int SCRAMBLING_MODE_MULTI2 =
+            android.hardware.cas.V1_2.ScramblingMode.MULTI2;
+    /**
+     * Advanced Encryption System (AES) 128-bit Encryption mode.
+     */
+    public static final int SCRAMBLING_MODE_AES128 =
+            android.hardware.cas.V1_2.ScramblingMode.AES128;
+    /**
+     * Advanced Encryption System (AES) Electronic Code Book (ECB) mode.
+     */
+    public static final int SCRAMBLING_MODE_AES_ECB =
+            android.hardware.cas.V1_2.ScramblingMode.AES_ECB;
+    /**
+     * Advanced Encryption System (AES) Society of Cable Telecommunications Engineers (SCTE) 52
+     * mode.
+     */
+    public static final int SCRAMBLING_MODE_AES_SCTE52 =
+            android.hardware.cas.V1_2.ScramblingMode.AES_SCTE52;
+    /**
+     * Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode.
+     */
+    public static final int SCRAMBLING_MODE_TDES_ECB =
+            android.hardware.cas.V1_2.ScramblingMode.TDES_ECB;
+    /**
+     * Triple Data Encryption Algorithm (TDES) Society of Cable Telecommunications Engineers (SCTE)
+     * 52 mode.
+     */
+    public static final int SCRAMBLING_MODE_TDES_SCTE52 =
+            android.hardware.cas.V1_2.ScramblingMode.TDES_SCTE52;
+
+    /**
+     * Usages used to open cas sessions.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "SESSION_USAGE_",
+            value = {SESSION_USAGE_LIVE, SESSION_USAGE_PLAYBACK, SESSION_USAGE_RECORD,
+            SESSION_USAGE_TIMESHIFT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SessionUsage {}
+    /**
+     * Cas session is used to descramble live streams.
+     */
+    public static final int SESSION_USAGE_LIVE = android.hardware.cas.V1_2.SessionIntent.LIVE;
+    /**
+     * Cas session is used to descramble recoreded streams.
+     */
+    public static final int SESSION_USAGE_PLAYBACK =
+            android.hardware.cas.V1_2.SessionIntent.PLAYBACK;
+    /**
+     * Cas session is used to descramble live streams and encrypt local recorded content
+     */
+    public static final int SESSION_USAGE_RECORD = android.hardware.cas.V1_2.SessionIntent.RECORD;
+    /**
+     * Cas session is used to descramble live streams , encrypt local recorded content and playback
+     * local encrypted content.
+     */
+    public static final int SESSION_USAGE_TIMESHIFT =
+            android.hardware.cas.V1_2.SessionIntent.TIMESHIFT;
+
+    /**
+     * Plugin status events sent from cas system.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "PLUGIN_STATUS_",
+            value = {PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED, PLUGIN_STATUS_SESSION_NUMBER_CHANGED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PluginStatus {}
+
+    /**
+     * The event to indicate that the status of CAS system is changed by the removal or insertion of
+     * physical CAS modules.
+     */
+    public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED =
+            android.hardware.cas.V1_2.StatusEvent.PLUGIN_PHYSICAL_MODULE_CHANGED;
+    /**
+     * The event to indicate that the number of CAS system's session is changed.
+     */
+    public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED =
+            android.hardware.cas.V1_2.StatusEvent.PLUGIN_SESSION_NUMBER_CHANGED;
 
     private static final Singleton<IMediaCasService> sService = new Singleton<IMediaCasService>() {
         @Override
         protected IMediaCasService create() {
             try {
-                Log.d(TAG, "Tried to get cas@1.1 service");
-                android.hardware.cas.V1_1.IMediaCasService serviceV11 =
-                        android.hardware.cas.V1_1.IMediaCasService.getService(true /*wait*/);
-                if (serviceV11 != null) {
-                    return serviceV11;
+                Log.d(TAG, "Trying to get cas@1.2 service");
+                android.hardware.cas.V1_2.IMediaCasService serviceV12 =
+                        android.hardware.cas.V1_2.IMediaCasService.getService(true /*wait*/);
+                if (serviceV12 != null) {
+                    return serviceV12;
                 }
-            } catch (Exception eV1_1) {
-                try {
-                    Log.d(TAG, "Tried to get cas@1.0 service");
-                    return IMediaCasService.getService(true /*wait*/);
-                } catch (Exception eV1_0) {
-                    Log.d(TAG, "Failed to get cas@1.0 service");
-                }
+            } catch (Exception eV1_2) {
+                Log.d(TAG, "Failed to get cas@1.2 service");
             }
+
+            try {
+                    Log.d(TAG, "Trying to get cas@1.1 service");
+                    android.hardware.cas.V1_1.IMediaCasService serviceV11 =
+                            android.hardware.cas.V1_1.IMediaCasService.getService(true /*wait*/);
+                    if (serviceV11 != null) {
+                        return serviceV11;
+                    }
+            } catch (Exception eV1_1) {
+                Log.d(TAG, "Failed to get cas@1.1 service");
+            }
+
+            try {
+                Log.d(TAG, "Trying to get cas@1.0 service");
+                return IMediaCasService.getService(true /*wait*/);
+            } catch (Exception eV1_0) {
+                Log.d(TAG, "Failed to get cas@1.0 service");
+            }
+
             return null;
         }
     };
@@ -139,6 +300,7 @@
     private void cleanupAndRethrowIllegalState() {
         mICas = null;
         mICasV11 = null;
+        mICasV12 = null;
         throw new IllegalStateException();
     }
 
@@ -146,6 +308,8 @@
 
         private static final int MSG_CAS_EVENT = 0;
         private static final int MSG_CAS_SESSION_EVENT = 1;
+        private static final int MSG_CAS_STATUS_EVENT = 2;
+        private static final int MSG_CAS_RESOURCE_LOST = 3;
         private static final String SESSION_KEY = "sessionId";
         private static final String DATA_KEY = "data";
 
@@ -164,6 +328,10 @@
                 mListener.onSessionEvent(MediaCas.this,
                         createFromSessionId(sessionId), msg.arg1, msg.arg2,
                         bundle.getByteArray(DATA_KEY));
+            } else if (msg.what == MSG_CAS_STATUS_EVENT) {
+                mListener.onPluginStatusUpdate(MediaCas.this, msg.arg1, msg.arg2);
+            } else if (msg.what == MSG_CAS_RESOURCE_LOST) {
+                mListener.onResourceLost(MediaCas.this);
             }
         }
     }
@@ -189,6 +357,12 @@
             msg.setData(bundle);
             mEventHandler.sendMessage(msg);
         }
+        @Override
+        public void onStatusUpdate(byte status, int arg)
+                throws RemoteException {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(
+                    EventHandler.MSG_CAS_STATUS_EVENT, status, arg));
+        }
     };
     /**
      * Describe a CAS plugin with its CA_system_ID and string name.
@@ -257,7 +431,7 @@
         final ArrayList<Byte> mSessionId;
 
         Session(@NonNull ArrayList<Byte> sessionId) {
-            mSessionId = sessionId;
+            mSessionId = new ArrayList<Byte>(sessionId);
         }
 
         /**
@@ -364,6 +538,19 @@
         }
 
         /**
+         * Get Session Id.
+         *
+         * @return session Id of the session.
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         */
+        @NonNull
+        public byte[] getSessionId() {
+            validateInternalStates();
+            return toBytes(mSessionId);
+        }
+
+        /**
          * Close the session.
          *
          * @throws IllegalStateException if the MediaCas instance is not valid.
@@ -445,14 +632,23 @@
     public MediaCas(int CA_system_id) throws UnsupportedCasException {
         try {
             IMediaCasService service = getService();
-            android.hardware.cas.V1_1.IMediaCasService serviceV11 =
+            android.hardware.cas.V1_2.IMediaCasService serviceV12 =
+                    android.hardware.cas.V1_2.IMediaCasService.castFrom(service);
+            if (serviceV12 == null) {
+                android.hardware.cas.V1_1.IMediaCasService serviceV11 =
                     android.hardware.cas.V1_1.IMediaCasService.castFrom(service);
-            if (serviceV11 == null) {
-                Log.d(TAG, "Used cas@1_0 interface to create plugin");
-                mICas = service.createPlugin(CA_system_id, mBinder);
+                if (serviceV11 == null) {
+                    Log.d(TAG, "Used cas@1_0 interface to create plugin");
+                    mICas = service.createPlugin(CA_system_id, mBinder);
+                } else {
+                    Log.d(TAG, "Used cas@1.1 interface to create plugin");
+                    mICas = mICasV11 = serviceV11.createPluginExt(CA_system_id, mBinder);
+                }
             } else {
-                Log.d(TAG, "Used cas@1.1 interface to create plugin");
-                mICas = mICasV11 = serviceV11.createPluginExt(CA_system_id, mBinder);
+                Log.d(TAG, "Used cas@1.2 interface to create plugin");
+                mICas = mICasV11 = mICasV12 =
+                    android.hardware.cas.V1_2.ICas
+                    .castFrom(serviceV12.createPluginExt(CA_system_id, mBinder));
             }
         } catch(Exception e) {
             Log.e(TAG, "Failed to create plugin: " + e);
@@ -465,6 +661,24 @@
         }
     }
 
+    /**
+     * Instantiate a CA system of the specified system id.
+     *
+     * @param casSystemId The system id of the CA system.
+     * @param tvInputServiceSessionId The Id of the session opened in TV Input Service (TIS)
+     *        {@link android.media.tv.TvInputService#onCreateSession(String, String)}
+     * @param priorityHint priority hint from the use case type for new created CAS system.
+     *
+     * @throws UnsupportedCasException if the device does not support the
+     * specified CA system.
+     */
+    public MediaCas(int casSystemId, @Nullable String tvInputServiceSessionId,
+            @PriorityHintUseCaseType int priorityHint)  throws UnsupportedCasException {
+        this(casSystemId);
+        mPriorityHint = priorityHint;
+        mTvInputServiceSessionId = tvInputServiceSessionId;
+    }
+
     IHwBinder getBinder() {
         validateInternalStates();
 
@@ -476,6 +690,7 @@
      * to receives scheme-specific notifications from a MediaCas instance.
      */
     public interface EventListener {
+
         /**
          * Notify the listener of a scheme-specific event from the CA system.
          *
@@ -501,6 +716,27 @@
                 int event, int arg, @Nullable byte[] data) {
             Log.d(TAG, "Received MediaCas Session event");
         }
+
+        /**
+         * Notify the listener that the cas plugin status is updated.
+         *
+         * @param mediaCas the MediaCas object to receive this event.
+         * @param status the plugin status which is updated.
+         * @param arg an integer whose meaning is specific to the status to be updated.
+         */
+        default void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status,
+                int arg) {
+            Log.d(TAG, "Received MediaCas Plugin Status event");
+        }
+
+        /**
+         * Notify the listener that the session resources was lost.
+         *
+         * @param mediaCas the MediaCas object to receive this event.
+         */
+        default void onResourceLost(@NonNull MediaCas mediaCas) {
+            Log.d(TAG, "Received MediaCas Resource Reclaim event");
+        }
     }
 
     /**
@@ -563,6 +799,20 @@
             mSession = createFromSessionId(sessionId);
         }
     }
+
+    private class OpenSession_1_2_Callback implements
+            android.hardware.cas.V1_2.ICas.openSession_1_2Callback {
+
+        public Session mSession;
+        public int mStatus;
+
+        @Override
+        public void onValues(int status, ArrayList<Byte> sessionId) {
+            mStatus = status;
+            mSession = createFromSessionId(sessionId);
+        }
+    }
+
     /**
      * Open a session to descramble one or more streams scrambled by the
      * conditional access system.
@@ -588,6 +838,40 @@
     }
 
     /**
+     * Open a session with usage and scrambling information, so that descrambler can be configured
+     * to descramble one or more streams scrambled by the conditional access system.
+     *
+     * @param sessionUsage used for the created session.
+     * @param scramblingMode used for the created session.
+     *
+     * @return session the newly opened session.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    @Nullable
+    public Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode)
+            throws MediaCasException {
+        validateInternalStates();
+
+        if (mICasV12 == null) {
+            Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface");
+            throw new UnsupportedCasException("Open Session with scrambling mode is not supported");
+        }
+
+        try {
+            OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback();
+            mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb);
+            MediaCasException.throwExceptionIfNeeded(cb.mStatus);
+            return cb.mSession;
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+        return null;
+    }
+
+    /**
      * Send a received EMM packet to the CA system.
      *
      * @param data byte array of the EMM data.
diff --git a/media/java/android/media/MediaCasException.java b/media/java/android/media/MediaCasException.java
index 35fb104..349e9b3 100644
--- a/media/java/android/media/MediaCasException.java
+++ b/media/java/android/media/MediaCasException.java
@@ -16,7 +16,7 @@
 
 package android.media;
 
-import android.hardware.cas.V1_0.Status;
+import android.hardware.cas.V1_2.Status;
 
 /**
  * Base class for MediaCas exceptions
@@ -85,4 +85,15 @@
             super(detailMessage);
         }
     }
+
+    /**
+     * Exception thrown when an operation on a MediaCas object is attempted
+     * and hardware resources are not sufficient to allocate, due to client's lower priority.
+     */
+    public static final class InsufficientResourceException extends MediaCasException {
+        /** @hide */
+        public InsufficientResourceException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
 }
diff --git a/media/java/android/media/MediaCasStateException.java b/media/java/android/media/MediaCasStateException.java
index 26c5792..8dbc9f4 100644
--- a/media/java/android/media/MediaCasStateException.java
+++ b/media/java/android/media/MediaCasStateException.java
@@ -18,8 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-
-import android.hardware.cas.V1_0.Status;
+import android.hardware.cas.V1_2.Status;
 
 /**
  * Base class for MediaCas runtime exceptions
@@ -48,39 +47,60 @@
 
         String diagnosticInfo = "";
         switch (err) {
-        case Status.ERROR_CAS_UNKNOWN:
-            diagnosticInfo = "General CAS error";
-            break;
-        case Status.ERROR_CAS_NO_LICENSE:
-            diagnosticInfo = "No license";
-            break;
-        case Status.ERROR_CAS_LICENSE_EXPIRED:
-            diagnosticInfo = "License expired";
-            break;
-        case Status.ERROR_CAS_SESSION_NOT_OPENED:
-            diagnosticInfo = "Session not opened";
-            break;
-        case Status.ERROR_CAS_CANNOT_HANDLE:
-            diagnosticInfo = "Unsupported scheme or data format";
-            break;
-        case Status.ERROR_CAS_INVALID_STATE:
-            diagnosticInfo = "Invalid CAS state";
-            break;
-        case Status.ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION:
-            diagnosticInfo = "Insufficient output protection";
-            break;
-        case Status.ERROR_CAS_TAMPER_DETECTED:
-            diagnosticInfo = "Tamper detected";
-            break;
-        case Status.ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED:
-            diagnosticInfo = "Not initialized";
-            break;
-        case Status.ERROR_CAS_DECRYPT:
-            diagnosticInfo = "Decrypt error";
-            break;
-        default:
-            diagnosticInfo = "Unknown CAS state exception";
-            break;
+            case Status.ERROR_CAS_UNKNOWN:
+                diagnosticInfo = "General CAS error";
+                break;
+            case Status.ERROR_CAS_NO_LICENSE:
+                diagnosticInfo = "No license";
+                break;
+            case Status.ERROR_CAS_LICENSE_EXPIRED:
+                diagnosticInfo = "License expired";
+                break;
+            case Status.ERROR_CAS_SESSION_NOT_OPENED:
+                diagnosticInfo = "Session not opened";
+                break;
+            case Status.ERROR_CAS_CANNOT_HANDLE:
+                diagnosticInfo = "Unsupported scheme or data format";
+                break;
+            case Status.ERROR_CAS_INVALID_STATE:
+                diagnosticInfo = "Invalid CAS state";
+                break;
+            case Status.ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION:
+                diagnosticInfo = "Insufficient output protection";
+                break;
+            case Status.ERROR_CAS_TAMPER_DETECTED:
+                diagnosticInfo = "Tamper detected";
+                break;
+            case Status.ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED:
+                diagnosticInfo = "Not initialized";
+                break;
+            case Status.ERROR_CAS_DECRYPT:
+                diagnosticInfo = "Decrypt error";
+                break;
+            case Status.ERROR_CAS_NEED_ACTIVATION:
+                diagnosticInfo = "Need Activation";
+                break;
+            case Status.ERROR_CAS_NEED_PAIRING:
+                diagnosticInfo = "Need Pairing";
+                break;
+            case Status.ERROR_CAS_NO_CARD:
+                diagnosticInfo = "No Card";
+                break;
+            case Status.ERROR_CAS_CARD_MUTE:
+                diagnosticInfo = "Card Muted";
+                break;
+            case Status.ERROR_CAS_CARD_INVALID:
+                diagnosticInfo = "Card Invalid";
+                break;
+            case Status.ERROR_CAS_BLACKOUT:
+                diagnosticInfo = "Blackout";
+                break;
+            case Status.ERROR_CAS_REBOOTING:
+                diagnosticInfo = "Rebooting";
+                break;
+            default:
+                diagnosticInfo = "Unknown CAS state exception";
+                break;
         }
         throw new MediaCasStateException(err, msg,
                 String.format("%s (err=%d)", diagnosticInfo, err));
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 79b3886..1a0f139 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -100,6 +100,8 @@
  * <tr><td>{@link #KEY_AAC_DRC_HEAVY_COMPRESSION}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies whether to use heavy compression.</td></tr>
  * <tr><td>{@link #KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the maximum number of channels the decoder outputs.</td></tr>
  * <tr><td>{@link #KEY_AAC_DRC_EFFECT_TYPE}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the MPEG-D DRC effect type to use.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_OUTPUT_LOUDNESS}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, returns the DRC output loudness.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_ALBUM_MODE}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the whether MPEG-D DRC Album Mode is active or not.</td></tr>
  * <tr><td>{@link #KEY_CHANNEL_MASK}</td><td>Integer</td><td>optional, a mask of audio channel assignments</td></tr>
  * <tr><td>{@link #KEY_ENCODER_DELAY}</td><td>Integer</td><td>optional, the number of frames to trim from the start of the decoded audio stream.</td></tr>
  * <tr><td>{@link #KEY_ENCODER_PADDING}</td><td>Integer</td><td>optional, the number of frames to trim from the end of the decoded audio stream.</td></tr>
@@ -736,6 +738,37 @@
     public static final String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
 
     /**
+     * A key to retrieve the output loudness of a decoded bitstream.
+     * <p>If loudness normalization is active, the value corresponds to the Target Reference Level
+     * (see {@link #KEY_AAC_DRC_TARGET_REFERENCE_LEVEL}).<br>
+     * If loudness normalization is not active, the value corresponds to the loudness metadata
+     * given in the bitstream.
+     * <p>The value is retrieved with getInteger() and is given as an integer value between 0 and
+     * 231. It is calculated as -4 * Output Loudness in LKFS. Therefore, it represents the range of
+     * 0 to -57.75 LKFS.
+     * <p>A value of -1 indicates that no loudness metadata is present in the bitstream.
+     * <p>Loudness metadata can originate from MPEG-4 DRC or MPEG-D DRC.
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_OUTPUT_LOUDNESS = "aac-drc-output-loudness";
+
+    /**
+     * A key describing the album mode for MPEG-D DRC as defined in ISO/IEC 23003-4.
+     * <p>The associated value is an integer and can be set to following values:
+     * <table>
+     * <tr><th>Value</th><th>Album Mode</th></tr>
+     * <tr><th>0</th><th>disabled</th></tr>
+     * <tr><th>1</th><th>enabled</th></tr>
+     * </table>
+     * <p>Disabled album mode leads to application of gain sequences for fading in and out, if
+     * provided in the bitstream. Enabled album mode makes use of dedicated album loudness
+     * information, if provided in the bitstream.
+     * <p>The default value is 0 (album mode disabled).
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode";
+
+    /**
      * A key describing the FLAC compression level to be used (FLAC audio format only).
      * The associated value is an integer ranging from 0 (fastest, least compression)
      * to 8 (slowest, most compression).
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 239dfed..eae13d0 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -134,6 +134,59 @@
      */
     public static final int DEVICE_TYPE_BLUETOOTH = 3;
 
+    /**
+     * Media feature: Live audio.
+     * <p>
+     * A route that supports live audio routing will allow the media audio stream
+     * to be sent to supported destinations.  This can include internal speakers or
+     * audio jacks on the device itself, A2DP devices, and more.
+     * </p><p>
+     * When a live audio route is selected, audio routing is transparent to the application.
+     * All audio played on the media stream will be routed to the selected destination.
+     * </p><p>
+     * Refer to the class documentation for details about live audio routes.
+     * </p>
+     */
+    public static final String FEATURE_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+
+    /**
+     * Media feature: Live video.
+     * <p>
+     * A route that supports live video routing will allow a mirrored version
+     * of the device's primary display or a customized
+     * {@link android.app.Presentation Presentation} to be sent to supported
+     * destinations.
+     * </p><p>
+     * When a live video route is selected, audio and video routing is transparent
+     * to the application.  By default, audio and video is routed to the selected
+     * destination.  For certain live video routes, the application may also use a
+     * {@link android.app.Presentation Presentation} to replace the mirrored view
+     * on the external display with different content.
+     * </p><p>
+     * Refer to the class documentation for details about live video routes.
+     * </p>
+     *
+     * @see android.app.Presentation
+     */
+    public static final String FEATURE_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+
+    /**
+     * Media feature: Remote playback.
+     * <p>
+     * A route that supports remote playback routing will allow an application to send
+     * requests to play content remotely to supported destinations.
+     * </p><p>
+     * Remote playback routes destinations operate independently of the local device.
+     * When a remote playback route is selected, the application can control the content
+     * playing on the destination using {@link MediaRouter2.RoutingController#getControlHints()}.
+     * The application may also receive status updates from the route regarding remote playback.
+     * </p><p>
+     * Refer to the class documentation for details about remote playback routes.
+     * </p>
+     */
+    public static final String FEATURE_REMOTE_PLAYBACK =
+            "android.media.intent.category.REMOTE_PLAYBACK";
+
     final String mId;
     final CharSequence mName;
     final List<String> mFeatures;
@@ -260,9 +313,8 @@
     }
 
     /**
-     * Gets the package name of the client that uses the route.
-     * Returns null if no clients use this route.
-     * @hide
+     * Gets the package name of the app using the route.
+     * Returns null if no apps are using this route.
      */
     @Nullable
     public String getClientPackageName() {
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index 6bfa851..1e8b188 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
+import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Service;
@@ -64,7 +65,6 @@
      * request.
      *
      * @see #notifySessionCreated(RoutingSessionInfo, long)
-     * @hide
      */
     public static final long REQUEST_ID_UNKNOWN = 0;
 
@@ -82,8 +82,14 @@
         mHandler = new Handler(Looper.getMainLooper());
     }
 
+    /**
+     * If overriding this method, call through to the super method for any unknown actions.
+     * <p>
+     * {@inheritDoc}
+     */
+    @CallSuper
     @Override
-    @NonNull
+    @Nullable
     public IBinder onBind(@NonNull Intent intent) {
         //TODO: Allow binding from media router service only?
         if (SERVICE_INTERFACE.equals(intent.getAction())) {
@@ -110,7 +116,6 @@
      *
      * @param routeId the id of the route
      * @param volume the target volume
-     * @hide
      */
     public abstract void onSetVolume(@NonNull String routeId, int volume);
 
@@ -119,7 +124,6 @@
      *
      * @param routeId id of the route
      * @param delta the delta to add to the current volume
-     * @hide
      */
     public abstract void onUpdateVolume(@NonNull String routeId, int delta);
 
@@ -129,7 +133,6 @@
      * @param sessionId id of the session
      * @return information of the session with the given id.
      *         null if the session is released or ID is not valid.
-     * @hide
      */
     @Nullable
     public final RoutingSessionInfo getSessionInfo(@NonNull String sessionId) {
@@ -143,7 +146,6 @@
 
     /**
      * Gets the list of {@link RoutingSessionInfo session info} that the provider service maintains.
-     * @hide
      */
     @NonNull
     public final List<RoutingSessionInfo> getAllSessionInfo() {
@@ -163,7 +165,7 @@
      * @param requestId id of the previous request to create this session provided in
      *                  {@link #onCreateSession(String, String, long, Bundle)}
      * @see #onCreateSession(String, String, long, Bundle)
-     * @hide
+     * @see #getSessionInfo(String)
      */
     public final void notifySessionCreated(@NonNull RoutingSessionInfo sessionInfo,
             long requestId) {
@@ -197,7 +199,6 @@
      * @param requestId id of the previous request to create the session provided in
      *                  {@link #onCreateSession(String, String, long, Bundle)}.
      * @see #onCreateSession(String, String, long, Bundle)
-     * @hide
      */
     public final void notifySessionCreationFailed(long requestId) {
         if (mClient == null) {
@@ -213,8 +214,6 @@
     /**
      * Notifies the existing session is updated. For example, when
      * {@link RoutingSessionInfo#getSelectedRoutes() selected routes} are changed.
-     *
-     * @hide
      */
     public final void notifySessionUpdated(@NonNull RoutingSessionInfo sessionInfo) {
         Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
@@ -244,7 +243,6 @@
      *
      * @param sessionId id of the released session.
      * @see #onReleaseSession(String)
-     * @hide
      */
     public final void notifySessionReleased(@NonNull String sessionId) {
         if (TextUtils.isEmpty(sessionId)) {
@@ -296,7 +294,6 @@
      * @see RoutingSessionInfo.Builder#Builder(String, String)
      * @see RoutingSessionInfo.Builder#addSelectedRoute(String)
      * @see RoutingSessionInfo.Builder#setControlHints(Bundle)
-     * @hide
      */
     public abstract void onCreateSession(@NonNull String packageName, @NonNull String routeId,
             long requestId, @Nullable Bundle sessionHints);
@@ -314,7 +311,6 @@
      * @param sessionId id of the session being released.
      * @see #notifySessionReleased(String)
      * @see #getSessionInfo(String)
-     * @hide
      */
     public abstract void onReleaseSession(@NonNull String sessionId);
 
@@ -326,7 +322,6 @@
      *
      * @param sessionId id of the session
      * @param routeId id of the route
-     * @hide
      */
     public abstract void onSelectRoute(@NonNull String sessionId, @NonNull String routeId);
 
@@ -338,7 +333,6 @@
      *
      * @param sessionId id of the session
      * @param routeId id of the route
-     * @hide
      */
     public abstract void onDeselectRoute(@NonNull String sessionId, @NonNull String routeId);
 
@@ -350,7 +344,6 @@
      *
      * @param sessionId id of the session
      * @param routeId id of the route
-     * @hide
      */
     public abstract void onTransferToRoute(@NonNull String sessionId, @NonNull String routeId);
 
@@ -370,9 +363,8 @@
      * </p>
      *
      * @param preference the new discovery preference
-     *
-     * TODO: This method needs tests.
      */
+    // TODO: This method needs tests.
     public void onDiscoveryPreferenceChanged(@NonNull RouteDiscoveryPreference preference) {}
 
     /**
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 51d08ec..18670e9 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -35,6 +35,7 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -49,9 +50,9 @@
  * Media Router 2 allows applications to control the routing of media channels
  * and streams from the current device to remote speakers and devices.
  *
- * TODO: Add method names at the beginning of log messages. (e.g. changeSessionInfoOnHandler)
- *       Not only MediaRouter2, but also to service / manager / provider.
  */
+// TODO: Add method names at the beginning of log messages. (e.g. updateControllerOnHandler)
+//       Not only MediaRouter2, but also to service / manager / provider.
 public class MediaRouter2 {
     private static final String TAG = "MR2";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -66,16 +67,18 @@
     private final CopyOnWriteArrayList<RouteCallbackRecord> mRouteCallbackRecords =
             new CopyOnWriteArrayList<>();
 
-    private final CopyOnWriteArrayList<SessionCallbackRecord> mSessionCallbackRecords =
+    private final CopyOnWriteArrayList<ControllerCallbackRecord> mControllerCallbackRecords =
             new CopyOnWriteArrayList<>();
 
-    private final CopyOnWriteArrayList<SessionCreationRequest> mSessionCreationRequests =
+    private final CopyOnWriteArrayList<ControllerCreationRequest> mControllerCreationRequests =
             new CopyOnWriteArrayList<>();
 
     private final String mPackageName;
     @GuardedBy("sRouterLock")
     final Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
 
+    final RoutingController mSystemController;
+
     @GuardedBy("sRouterLock")
     private RouteDiscoveryPreference mDiscoveryPreference = RouteDiscoveryPreference.EMPTY;
 
@@ -86,13 +89,13 @@
     @GuardedBy("sRouterLock")
     private Map<String, RoutingController> mRoutingControllers = new ArrayMap<>();
 
-    private AtomicInteger mSessionCreationRequestCnt = new AtomicInteger(1);
+    private AtomicInteger mControllerCreationRequestCnt = new AtomicInteger(1);
 
     final Handler mHandler;
     @GuardedBy("sRouterLock")
     private boolean mShouldUpdateRoutes;
     private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
-    private volatile OnCreateSessionListener mOnCreateSessionListener;
+    private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
 
     /**
      * Gets an instance of the media router associated with the context.
@@ -116,19 +119,26 @@
         mHandler = new Handler(Looper.getMainLooper());
 
         List<MediaRoute2Info> currentSystemRoutes = null;
+        RoutingSessionInfo currentSystemSessionInfo = null;
         try {
             currentSystemRoutes = mMediaRouterService.getSystemRoutes();
+            currentSystemSessionInfo = mMediaRouterService.getSystemSessionInfo();
         } catch (RemoteException ex) {
-            Log.e(TAG, "Unable to get current currentSystemRoutes", ex);
+            Log.e(TAG, "Unable to get current system's routes / session info", ex);
         }
 
         if (currentSystemRoutes == null || currentSystemRoutes.isEmpty()) {
             throw new RuntimeException("Null or empty currentSystemRoutes. Something is wrong.");
         }
 
+        if (currentSystemSessionInfo == null) {
+            throw new RuntimeException("Null currentSystemSessionInfo. Something is wrong.");
+        }
+
         for (MediaRoute2Info route : currentSystemRoutes) {
             mRoutes.put(route.getId(), route);
         }
+        mSystemController = new SystemRoutingController(currentSystemSessionInfo);
     }
 
     /**
@@ -242,23 +252,22 @@
     }
 
     /**
-     * Registers a callback to get updates on creations and changes of routing sessions.
+     * Registers a callback to get updates on creations and changes of
+     * {@link RoutingController routing controllers}.
      * If you register the same callback twice or more, it will be ignored.
      *
      * @param executor the executor to execute the callback on
      * @param callback the callback to register
-     * @see #unregisterSessionCallback
-     * @hide
+     * @see #unregisterControllerCallback
      */
-    @NonNull
-    public void registerSessionCallback(@CallbackExecutor Executor executor,
-            @NonNull SessionCallback callback) {
+    public void registerControllerCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull RoutingControllerCallback callback) {
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(callback, "callback must not be null");
 
-        SessionCallbackRecord record = new SessionCallbackRecord(executor, callback);
-        if (!mSessionCallbackRecords.addIfAbsent(record)) {
-            Log.w(TAG, "Ignoring the same session callback");
+        ControllerCallbackRecord record = new ControllerCallbackRecord(executor, callback);
+        if (!mControllerCallbackRecords.addIfAbsent(record)) {
+            Log.w(TAG, "Ignoring the same controller callback");
             return;
         }
     }
@@ -268,59 +277,54 @@
      * If the callback has not been added or been removed already, it is ignored.
      *
      * @param callback the callback to unregister
-     * @see #registerSessionCallback
-     * @hide
+     * @see #registerControllerCallback
      */
-    @NonNull
-    public void unregisterSessionCallback(@NonNull SessionCallback callback) {
+    public void unregisterControllerCallback(@NonNull RoutingControllerCallback callback) {
         Objects.requireNonNull(callback, "callback must not be null");
 
-        if (!mSessionCallbackRecords.remove(new SessionCallbackRecord(null, callback))) {
-            Log.w(TAG, "Ignoring unknown session callback");
+        if (!mControllerCallbackRecords.remove(new ControllerCallbackRecord(null, callback))) {
+            Log.w(TAG, "Ignoring unknown controller callback");
             return;
         }
     }
 
     /**
-     * Sets an {@link OnCreateSessionListener} to send hints when creating a session.
-     * To send the hints, listener should be set <em>BEFORE</em> calling
-     * {@link #requestCreateSession(MediaRoute2Info)}.
+     * Sets an {@link OnGetControllerHintsListener} to send hints when creating a
+     * {@link RoutingController}. To send the hints, listener should be set <em>BEFORE</em> calling
+     * {@link #requestCreateController(MediaRoute2Info)}.
      *
-     * @param listener A listener to send optional app-specific hints when creating a session.
+     * @param listener A listener to send optional app-specific hints when creating a controller.
      *                 {@code null} for unset.
-     * @hide
      */
-    public void setOnCreateSessionListener(@Nullable OnCreateSessionListener listener) {
-        mOnCreateSessionListener = listener;
+    public void setOnGetControllerHintsListener(@Nullable OnGetControllerHintsListener listener) {
+        mOnGetControllerHintsListener = listener;
     }
 
     /**
-     * Requests the media route provider service to create a session with the given route.
+     * Requests the media route provider service to create a {@link RoutingController}
+     * with the given route.
      *
-     * @param route the route you want to create a session with.
+     * @param route the route you want to create a controller with.
      *
-     * @see SessionCallback#onSessionCreated
-     * @see SessionCallback#onSessionCreationFailed
-     * @hide
+     * @see RoutingControllerCallback#onControllerCreated
+     * @see RoutingControllerCallback#onControllerCreationFailed
      */
-    @NonNull
-    public void requestCreateSession(@NonNull MediaRoute2Info route) {
+    public void requestCreateController(@NonNull MediaRoute2Info route) {
         Objects.requireNonNull(route, "route must not be null");
         // TODO: Check the given route exists
 
         final int requestId;
-        requestId = mSessionCreationRequestCnt.getAndIncrement();
+        requestId = mControllerCreationRequestCnt.getAndIncrement();
 
-        SessionCreationRequest request = new SessionCreationRequest(requestId, route);
-        mSessionCreationRequests.add(request);
+        ControllerCreationRequest request = new ControllerCreationRequest(requestId, route);
+        mControllerCreationRequests.add(request);
 
-
-        OnCreateSessionListener listener = mOnCreateSessionListener;
-        Bundle sessionHints = null;
+        OnGetControllerHintsListener listener = mOnGetControllerHintsListener;
+        Bundle controllerHints = null;
         if (listener != null) {
-            sessionHints = listener.onCreateSession(route);
-            if (sessionHints != null) {
-                sessionHints = new Bundle(sessionHints);
+            controllerHints = listener.onGetControllerHints(route);
+            if (controllerHints != null) {
+                controllerHints = new Bundle(controllerHints);
             }
         }
 
@@ -330,10 +334,9 @@
         }
         if (client != null) {
             try {
-                mMediaRouterService.requestCreateSession(client, route, requestId,
-                        sessionHints);
+                mMediaRouterService.requestCreateSession(client, route, requestId, controllerHints);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to request to create session.", ex);
+                Log.e(TAG, "Unable to request to create controller.", ex);
                 mHandler.sendMessage(obtainMessage(MediaRouter2::createControllerOnHandler,
                         MediaRouter2.this, null, requestId));
             }
@@ -341,6 +344,41 @@
     }
 
     /**
+     * Gets a {@link RoutingController} which can control the routes provided by system.
+     * e.g. Phone speaker, wired headset, Bluetooth, etc.
+     * <p>
+     * Note: The system controller can't be released. Calling {@link RoutingController#release()}
+     * will be ignored.
+     * <p>
+     * This method will always return the same instance.
+     */
+    @NonNull
+    public RoutingController getSystemController() {
+        return mSystemController;
+    }
+
+    /**
+     * Gets the list of currently non-released {@link RoutingController routing controllers}.
+     * <p>
+     * Note: The list returned here will never be empty. The first element in the list is
+     * always the {@link #getSystemController() system controller}.
+     */
+    @NonNull
+    public List<RoutingController> getControllers() {
+        List<RoutingController> result = new ArrayList<>();
+        result.add(0, mSystemController);
+
+        Collection<RoutingController> controllers;
+        synchronized (sRouterLock) {
+            controllers = mRoutingControllers.values();
+            if (controllers != null) {
+                result.addAll(controllers);
+            }
+        }
+        return result;
+    }
+
+    /**
      * Sends a media control request to be performed asynchronously by the route's destination.
      *
      * @param route the route that will receive the control request
@@ -468,15 +506,15 @@
     }
 
     /**
-     * Creates a controller and calls the {@link SessionCallback#onSessionCreated}.
-     * If session creation has failed, then it calls
-     * {@link SessionCallback#onSessionCreationFailed}.
+     * Creates a controller and calls the {@link RoutingControllerCallback#onControllerCreated}.
+     * If the controller creation has failed, then it calls
+     * {@link RoutingControllerCallback#onControllerCreationFailed}.
      * <p>
      * Pass {@code null} to sessionInfo for the failure case.
      */
     void createControllerOnHandler(@Nullable RoutingSessionInfo sessionInfo, int requestId) {
-        SessionCreationRequest matchingRequest = null;
-        for (SessionCreationRequest request : mSessionCreationRequests) {
+        ControllerCreationRequest matchingRequest = null;
+        for (ControllerCreationRequest request : mControllerCreationRequests) {
             if (request.mRequestId == requestId) {
                 matchingRequest = request;
                 break;
@@ -484,21 +522,21 @@
         }
 
         if (matchingRequest != null) {
-            mSessionCreationRequests.remove(matchingRequest);
+            mControllerCreationRequests.remove(matchingRequest);
 
             MediaRoute2Info requestedRoute = matchingRequest.mRoute;
 
             if (sessionInfo == null) {
                 // TODO: We may need to distinguish between failure and rejection.
                 //       One way can be introducing 'reason'.
-                notifySessionCreationFailed(requestedRoute);
+                notifyControllerCreationFailed(requestedRoute);
                 return;
             } else if (!sessionInfo.getSelectedRoutes().contains(requestedRoute.getId())) {
                 Log.w(TAG, "The session does not contain the requested route. "
                         + "(requestedRouteId=" + requestedRoute.getId()
                         + ", actualRoutes=" + sessionInfo.getSelectedRoutes()
                         + ")");
-                notifySessionCreationFailed(requestedRoute);
+                notifyControllerCreationFailed(requestedRoute);
                 return;
             } else if (!TextUtils.equals(requestedRoute.getProviderId(),
                     sessionInfo.getProviderId())) {
@@ -506,7 +544,7 @@
                         + "(requested route's providerId=" + requestedRoute.getProviderId()
                         + ", actual providerId=" + sessionInfo.getProviderId()
                         + ")");
-                notifySessionCreationFailed(requestedRoute);
+                notifyControllerCreationFailed(requestedRoute);
                 return;
             }
         }
@@ -514,15 +552,23 @@
         if (sessionInfo != null) {
             RoutingController controller = new RoutingController(sessionInfo);
             synchronized (sRouterLock) {
-                mRoutingControllers.put(controller.getSessionId(), controller);
+                mRoutingControllers.put(controller.getId(), controller);
             }
-            notifySessionCreated(controller);
+            notifyControllerCreated(controller);
         }
     }
 
-    void changeSessionInfoOnHandler(RoutingSessionInfo sessionInfo) {
+    void updateControllerOnHandler(RoutingSessionInfo sessionInfo) {
         if (sessionInfo == null) {
-            Log.w(TAG, "changeSessionInfoOnHandler: Ignoring null sessionInfo.");
+            Log.w(TAG, "updateControllerOnHandler: Ignoring null sessionInfo.");
+            return;
+        }
+
+        if (sessionInfo.isSystemSession()) {
+            // The session info is sent from SystemMediaRoute2Provider.
+            RoutingController systemController = getSystemController();
+            systemController.setRoutingSessionInfo(sessionInfo);
+            notifyControllerUpdated(systemController);
             return;
         }
 
@@ -532,20 +578,20 @@
         }
 
         if (matchingController == null) {
-            Log.w(TAG, "changeSessionInfoOnHandler: Matching controller not found. uniqueSessionId="
+            Log.w(TAG, "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
                     + sessionInfo.getId());
             return;
         }
 
         RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
         if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
-            Log.w(TAG, "changeSessionInfoOnHandler: Provider IDs are not matched. old="
+            Log.w(TAG, "updateControllerOnHandler: Provider IDs are not matched. old="
                     + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
             return;
         }
 
         matchingController.setRoutingSessionInfo(sessionInfo);
-        notifySessionInfoChanged(matchingController, oldInfo, sessionInfo);
+        notifyControllerUpdated(matchingController);
     }
 
     void releaseControllerOnHandler(RoutingSessionInfo sessionInfo) {
@@ -575,11 +621,15 @@
             return;
         }
 
+        boolean removed;
         synchronized (sRouterLock) {
-            mRoutingControllers.remove(uniqueSessionId, matchingController);
+            removed = mRoutingControllers.remove(uniqueSessionId, matchingController);
         }
-        matchingController.release();
-        notifyControllerReleased(matchingController);
+
+        if (removed) {
+            matchingController.release();
+            notifyControllerReleased(matchingController);
+        }
     }
 
     private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
@@ -620,33 +670,31 @@
         }
     }
 
-    private void notifySessionCreated(RoutingController controller) {
-        for (SessionCallbackRecord record: mSessionCallbackRecords) {
+    private void notifyControllerCreated(RoutingController controller) {
+        for (ControllerCallbackRecord record: mControllerCallbackRecords) {
             record.mExecutor.execute(
-                    () -> record.mSessionCallback.onSessionCreated(controller));
+                    () -> record.mControllerCallback.onControllerCreated(controller));
         }
     }
 
-    private void notifySessionCreationFailed(MediaRoute2Info route) {
-        for (SessionCallbackRecord record: mSessionCallbackRecords) {
+    private void notifyControllerCreationFailed(MediaRoute2Info route) {
+        for (ControllerCallbackRecord record: mControllerCallbackRecords) {
             record.mExecutor.execute(
-                    () -> record.mSessionCallback.onSessionCreationFailed(route));
+                    () -> record.mControllerCallback.onControllerCreationFailed(route));
         }
     }
 
-    private void notifySessionInfoChanged(RoutingController controller,
-            RoutingSessionInfo oldInfo, RoutingSessionInfo newInfo) {
-        for (SessionCallbackRecord record: mSessionCallbackRecords) {
+    private void notifyControllerUpdated(RoutingController controller) {
+        for (ControllerCallbackRecord record: mControllerCallbackRecords) {
             record.mExecutor.execute(
-                    () -> record.mSessionCallback.onSessionInfoChanged(
-                            controller, oldInfo, newInfo));
+                    () -> record.mControllerCallback.onControllerUpdated(controller));
         }
     }
 
     private void notifyControllerReleased(RoutingController controller) {
-        for (SessionCallbackRecord record: mSessionCallbackRecords) {
+        for (ControllerCallbackRecord record: mControllerCallbackRecords) {
             record.mExecutor.execute(
-                    () -> record.mSessionCallback.onSessionReleased(controller));
+                    () -> record.mControllerCallback.onControllerReleased(controller));
         }
     }
 
@@ -673,100 +721,86 @@
          * Called when routes are changed. For example, it is called when the route's name
          * or volume have been changed.
          *
-         * TODO: Write here what the developers should do when this method is called.
-         * How they can find the exact point how a route is changed?
-         * It can be a volume, name, client package name, ....
-         *
          * @param routes the list of routes that have been changed. It's never empty.
          */
         public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
     }
 
     /**
-     * Callback for receiving a result of session creation and session updates.
-     * @hide
+     * Callback for receiving a result of {@link RoutingController} creation and updates.
      */
-    public static class SessionCallback {
+    public static class RoutingControllerCallback {
         /**
-         * Called when the routing session is created by the route provider.
+         * Called when the {@link RoutingController} is created.
+         * A {@link RoutingController} can be created by calling
+         * {@link #requestCreateController(MediaRoute2Info)}, or by the system.
          *
-         * @param controller the controller to control the created session
+         * @param controller the controller to control routes
          */
-        public void onSessionCreated(@NonNull RoutingController controller) {}
+        public void onControllerCreated(@NonNull RoutingController controller) {}
 
         /**
-         * Called when the session creation request failed.
+         * Called when the controller creation request failed.
          *
-         * @param requestedRoute the route info which was used for the request
+         * @param requestedRoute the route info which was used for the creation request
          */
-        public void onSessionCreationFailed(@NonNull MediaRoute2Info requestedRoute) {}
+        public void onControllerCreationFailed(@NonNull MediaRoute2Info requestedRoute) {}
 
         /**
-         * Called when the session info has changed.
+         * Called when the controller is updated.
          *
-         * @param oldInfo the session info before the session changed.
-         * @prarm newInfo the changed session info
-         *
-         * TODO: (Discussion) Do we really need newInfo? The controller has the newInfo.
-         *       However. there can be timing issue if there is no newInfo.
+         * @param controller the updated controller. Can be the system controller.
+         * @see #getSystemController()
          */
-        public void onSessionInfoChanged(@NonNull RoutingController controller,
-                @NonNull RoutingSessionInfo oldInfo,
-                @NonNull RoutingSessionInfo newInfo) {}
+        public void onControllerUpdated(@NonNull RoutingController controller) {}
 
         /**
-         * Called when the session is released by {@link MediaRoute2ProviderService}.
-         * Before this method is called, the controller would be released by the system,
-         * which means the {@link RoutingController#isReleased()} will always return true
+         * Called when a routing controller is released. It can be released in two cases:
+         * <ul>
+         *     <li>When {@link RoutingController#release()} is called.</li>
+         *     <li>When the remote session in the provider is destroyed.</li>
+         * </ul>
+         * {@link RoutingController#isReleased()} will always return {@code true}
          * for the {@code controller} here.
-         * <p>
-         * Note: Calling {@link RoutingController#release()} will <em>NOT</em> trigger
-         * this method to be called.
          *
-         * TODO: Add tests for checking whether this method is called.
-         * TODO: When service process dies, this should be called.
-         *
+         * @see RoutingController#release()
          * @see RoutingController#isReleased()
          */
-        public void onSessionReleased(@NonNull RoutingController controller) {}
+        // TODO: Add tests for checking whether this method is called.
+        // TODO: When service process dies, this should be called.
+        public void onControllerReleased(@NonNull RoutingController controller) {}
     }
 
     /**
-     * A listener interface to send an optional app-specific hints when creating a session.
-     *
-     * @hide
+     * A listener interface to send an optional app-specific hints when creating the
+     * {@link RoutingController}.
      */
-    public interface OnCreateSessionListener {
+    public interface OnGetControllerHintsListener {
         /**
          * Called when the {@link MediaRouter2} is about to request
-         * the media route provider service to create a session with the given route.
-         * The {@link Bundle} returned here will be sent to media route provider service as a hint
-         * for creating a session.
+         * the media route provider service to create a controller with the given route.
+         * The {@link Bundle} returned here will be sent to media route provider service as a hint.
          * <p>
-         * To send hints when creating the session, set this listener before calling
-         * {@link #requestCreateSession(MediaRoute2Info)}.
-         * <p>
-         * This will be called on the same thread which calls
-         * {@link #requestCreateSession(MediaRoute2Info)}.
+         * To send hints when creating the controller, set the listener before calling
+         * {@link #requestCreateController(MediaRoute2Info)}. The method will be called
+         * on the same thread which calls {@link #requestCreateController(MediaRoute2Info)}.
          *
-         * @param route The route to create session with
+         * @param route The route to create controller with
          * @return An optional bundle of app-specific arguments to send to the provider,
          *         or null if none. The contents of this bundle may affect the result of
-         *         session creation.
+         *         controller creation.
          * @see MediaRoute2ProviderService#onCreateSession(String, String, long, Bundle)
          */
         @Nullable
-        Bundle onCreateSession(@NonNull MediaRoute2Info route);
+        Bundle onGetControllerHints(@NonNull MediaRoute2Info route);
     }
 
     /**
      * A class to control media routing session in media route provider.
      * For example, selecting/deselcting/transferring routes to session can be done through this
-     * class. Instances are created by {@link MediaRouter2}.
-     *
-     * @hide
+     * class. Instances are created by {@link #requestCreateController(MediaRoute2Info)}.
      */
-    public final class RoutingController {
+    public class RoutingController {
         private final Object mControllerLock = new Object();
 
         @GuardedBy("mControllerLock")
@@ -780,9 +814,10 @@
         }
 
         /**
-         * @return the ID of the session
+         * @return the ID of the controller
          */
-        public String getSessionId() {
+        @NonNull
+        public String getId() {
             synchronized (mControllerLock) {
                 return mSessionInfo.getId();
             }
@@ -839,7 +874,7 @@
         }
 
         /**
-         * Returns true if the session is released, false otherwise.
+         * Returns true if this controller is released, false otherwise.
          * If it is released, then all other getters from this instance may return invalid values.
          * Also, any operations to this instance will be ignored once released.
          *
@@ -862,7 +897,7 @@
          *
          * @see #getSelectedRoutes()
          * @see #getSelectableRoutes()
-         * @see SessionCallback#onSessionInfoChanged
+         * @see RoutingControllerCallback#onControllerUpdated
          */
         public void selectRoute(@NonNull MediaRoute2Info route) {
             Objects.requireNonNull(route, "route must not be null");
@@ -891,7 +926,7 @@
             }
             if (client != null) {
                 try {
-                    mMediaRouterService.selectRoute(client, getSessionId(), route);
+                    mMediaRouterService.selectRoute(client, getId(), route);
                 } catch (RemoteException ex) {
                     Log.e(TAG, "Unable to select route for session.", ex);
                 }
@@ -909,7 +944,7 @@
          *
          * @see #getSelectedRoutes()
          * @see #getDeselectableRoutes()
-         * @see SessionCallback#onSessionInfoChanged
+         * @see RoutingControllerCallback#onControllerUpdated
          */
         public void deselectRoute(@NonNull MediaRoute2Info route) {
             Objects.requireNonNull(route, "route must not be null");
@@ -938,7 +973,7 @@
             }
             if (client != null) {
                 try {
-                    mMediaRouterService.deselectRoute(client, getSessionId(), route);
+                    mMediaRouterService.deselectRoute(client, getId(), route);
                 } catch (RemoteException ex) {
                     Log.e(TAG, "Unable to remove route from session.", ex);
                 }
@@ -956,7 +991,7 @@
          *
          * @see #getSelectedRoutes()
          * @see #getTransferrableRoutes()
-         * @see SessionCallback#onSessionInfoChanged
+         * @see RoutingControllerCallback#onControllerUpdated
          */
         public void transferToRoute(@NonNull MediaRoute2Info route) {
             Objects.requireNonNull(route, "route must not be null");
@@ -986,7 +1021,7 @@
             }
             if (client != null) {
                 try {
-                    mMediaRouterService.transferToRoute(client, getSessionId(), route);
+                    mMediaRouterService.transferToRoute(client, getId(), route);
                 } catch (RemoteException ex) {
                     Log.e(TAG, "Unable to transfer to route for session.", ex);
                 }
@@ -997,9 +1032,8 @@
          * Release this controller and corresponding session.
          * Any operations on this controller after calling this method will be ignored.
          * The devices that are playing media will stop playing it.
-         *
-         * TODO: Add tests using {@link MediaRouter2Manager#getActiveSessions()}.
          */
+        // TODO: Add tests using {@link MediaRouter2Manager#getActiveSessions()}.
         public void release() {
             synchronized (mControllerLock) {
                 if (mIsReleased) {
@@ -1010,13 +1044,19 @@
             }
 
             Client2 client;
+            boolean removed;
             synchronized (sRouterLock) {
-                mRoutingControllers.remove(getSessionId(), this);
+                removed = mRoutingControllers.remove(getId(), this);
                 client = mClient;
             }
+
+            if (removed) {
+                mHandler.post(() -> notifyControllerReleased(RoutingController.this));
+            }
+
             if (client != null) {
                 try {
-                    mMediaRouterService.releaseSession(client, getSessionId());
+                    mMediaRouterService.releaseSession(client, getId());
                 } catch (RemoteException ex) {
                     Log.e(TAG, "Unable to notify of controller release", ex);
                 }
@@ -1037,7 +1077,7 @@
 
             StringBuilder result = new StringBuilder()
                     .append("RoutingController{ ")
-                    .append("sessionId=").append(getSessionId())
+                    .append("id=").append(getId())
                     .append(", selectedRoutes={")
                     .append(selectedRoutes)
                     .append("}")
@@ -1074,7 +1114,6 @@
         // TODO: This method uses two locks (mLock outside, sLock inside).
         //       Check if there is any possiblity of deadlock.
         private List<MediaRoute2Info> getRoutesWithIdsLocked(List<String> routeIds) {
-
             List<MediaRoute2Info> routes = new ArrayList<>();
             synchronized (sRouterLock) {
                 // TODO: Maybe able to change using Collection.stream()?
@@ -1089,6 +1128,23 @@
         }
     }
 
+    class SystemRoutingController extends RoutingController {
+        SystemRoutingController(@NonNull RoutingSessionInfo sessionInfo) {
+            super(sessionInfo);
+        }
+
+        @Override
+        public void release() {
+            // Do nothing. SystemRoutingController will never be released
+        }
+
+        @Override
+        public boolean isReleased() {
+            // SystemRoutingController will never be released
+            return false;
+        }
+    }
+
     final class RouteCallbackRecord {
         public final Executor mExecutor;
         public final RouteCallback mRouteCallback;
@@ -1118,13 +1174,13 @@
         }
     }
 
-    final class SessionCallbackRecord {
+    final class ControllerCallbackRecord {
         public final Executor mExecutor;
-        public final SessionCallback mSessionCallback;
+        public final RoutingControllerCallback mControllerCallback;
 
-        SessionCallbackRecord(@NonNull Executor executor,
-                @NonNull SessionCallback sessionCallback) {
-            mSessionCallback = sessionCallback;
+        ControllerCallbackRecord(@NonNull Executor executor,
+                @NonNull RoutingControllerCallback controllerCallback) {
+            mControllerCallback = controllerCallback;
             mExecutor = executor;
         }
 
@@ -1133,23 +1189,24 @@
             if (this == obj) {
                 return true;
             }
-            if (!(obj instanceof SessionCallbackRecord)) {
+            if (!(obj instanceof ControllerCallbackRecord)) {
                 return false;
             }
-            return mSessionCallback == ((SessionCallbackRecord) obj).mSessionCallback;
+            return mControllerCallback
+                    == ((ControllerCallbackRecord) obj).mControllerCallback;
         }
 
         @Override
         public int hashCode() {
-            return mSessionCallback.hashCode();
+            return mControllerCallback.hashCode();
         }
     }
 
-    final class SessionCreationRequest {
+    final class ControllerCreationRequest {
         public final MediaRoute2Info mRoute;
         public final int mRequestId;
 
-        SessionCreationRequest(int requestId, @NonNull MediaRoute2Info route) {
+        ControllerCreationRequest(int requestId, @NonNull MediaRoute2Info route) {
             mRoute = route;
             mRequestId = requestId;
         }
@@ -1185,7 +1242,7 @@
 
         @Override
         public void notifySessionInfoChanged(@Nullable RoutingSessionInfo sessionInfo) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2::changeSessionInfoOnHandler,
+            mHandler.sendMessage(obtainMessage(MediaRouter2::updateControllerOnHandler,
                     MediaRouter2.this, sessionInfo));
         }
 
diff --git a/media/java/android/media/MediaRouter2Utils.java b/media/java/android/media/MediaRouter2Utils.java
index 4904582..c15972d 100644
--- a/media/java/android/media/MediaRouter2Utils.java
+++ b/media/java/android/media/MediaRouter2Utils.java
@@ -29,9 +29,6 @@
     static final String TAG = "MR2Utils";
     static final String SEPARATOR = ":";
 
-    /**
-     * @hide
-     */
     @NonNull
     public static String toUniqueId(@NonNull String providerId, @NonNull String id) {
         if (TextUtils.isEmpty(providerId)) {
@@ -49,8 +46,6 @@
     /**
      * Gets provider ID from unique ID.
      * If the corresponding provider ID could not be generated, it will return null.
-     *
-     * @hide
      */
     @Nullable
     public static String getProviderId(@NonNull String uniqueId) {
@@ -75,8 +70,6 @@
     /**
      * Gets the original ID (i.e. non-unique route/session ID) from unique ID.
      * If the corresponding ID could not be generated, it will return null.
-     *
-     * @hide
      */
     @Nullable
     public static String getOriginalId(@NonNull String uniqueId) {
diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java
index 228adde..5383ea2 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -31,7 +31,6 @@
 
 /**
  * Describes a routing session which is created when a media route is selected.
- * @hide
  */
 public final class RoutingSessionInfo implements Parcelable {
     @NonNull
@@ -59,6 +58,7 @@
     final List<String> mTransferrableRoutes;
     @Nullable
     final Bundle mControlHints;
+    final boolean mIsSystemSession;
 
     RoutingSessionInfo(@NonNull Builder builder) {
         Objects.requireNonNull(builder, "builder must not be null.");
@@ -78,6 +78,7 @@
                 convertToUniqueRouteIds(builder.mTransferrableRoutes));
 
         mControlHints = builder.mControlHints;
+        mIsSystemSession = builder.mIsSystemSession;
     }
 
     RoutingSessionInfo(@NonNull Parcel src) {
@@ -93,6 +94,7 @@
         mTransferrableRoutes = ensureList(src.createStringArrayList());
 
         mControlHints = src.readBundle();
+        mIsSystemSession = src.readBoolean();
     }
 
     private static String ensureString(String str) {
@@ -193,6 +195,15 @@
         return mControlHints;
     }
 
+    /**
+     * Gets whether this session is in system media route provider.
+     * @hide
+     */
+    @Nullable
+    public boolean isSystemSession() {
+        return mIsSystemSession;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -208,6 +219,7 @@
         dest.writeStringList(mDeselectableRoutes);
         dest.writeStringList(mTransferrableRoutes);
         dest.writeBundle(mControlHints);
+        dest.writeBoolean(mIsSystemSession);
     }
 
     @Override
@@ -278,6 +290,7 @@
      * Builder class for {@link RoutingSessionInfo}.
      */
     public static final class Builder {
+        // TODO: Reorder these (important ones first)
         final String mId;
         final String mClientPackageName;
         String mProviderId;
@@ -286,6 +299,7 @@
         final List<String> mDeselectableRoutes;
         final List<String> mTransferrableRoutes;
         Bundle mControlHints;
+        boolean mIsSystemSession;
 
         /**
          * Constructor for builder to create {@link RoutingSessionInfo}.
@@ -333,6 +347,7 @@
             mTransferrableRoutes = new ArrayList<>(sessionInfo.mTransferrableRoutes);
 
             mControlHints = sessionInfo.mControlHints;
+            mIsSystemSession = sessionInfo.mIsSystemSession;
         }
 
         /**
@@ -491,6 +506,16 @@
         }
 
         /**
+         * Sets whether this session is in system media route provider.
+         * @hide
+         */
+        @NonNull
+        public Builder setSystemSession(boolean isSystemSession) {
+            mIsSystemSession = isSystemSession;
+            return this;
+        }
+
+        /**
          * Builds a routing session info.
          *
          * @throws IllegalArgumentException if no selected routes are added.
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 630d819..fc5d67d 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -110,12 +110,20 @@
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({VIDEO_UNAVAILABLE_REASON_UNKNOWN, VIDEO_UNAVAILABLE_REASON_TUNING,
-            VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL, VIDEO_UNAVAILABLE_REASON_BUFFERING,
-            VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY})
+        VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL, VIDEO_UNAVAILABLE_REASON_BUFFERING,
+        VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY, VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE,
+        VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION,
+        VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED,
+        VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED,
+        VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE, VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED,
+        VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION, VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING,
+        VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD, VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE,
+        VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID, VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT,
+        VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING, VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN})
     public @interface VideoUnavailableReason {}
 
     static final int VIDEO_UNAVAILABLE_REASON_START = 0;
-    static final int VIDEO_UNAVAILABLE_REASON_END = 5;
+    static final int VIDEO_UNAVAILABLE_REASON_END = 18;
 
     /**
      * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
@@ -151,9 +159,88 @@
      * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
      * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
      * the source is not physically connected, for example the HDMI cable is not connected.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 5;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the resource is not enough to meet requirement.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 6;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the output protection level enabled on the device is not sufficient to meet the requirements
+     * in the license policy.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 7;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the PVR record is not allowed by the license policy.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED = 8;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * no license keys have been provided.
      * @hide
      */
-    public static final int VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = VIDEO_UNAVAILABLE_REASON_END;
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE = 9;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * Using a license in whhich the keys have expired.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED = 10;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the device need be activated.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION = 11;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the device need be paired.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING = 12;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * smart card is missed.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD = 13;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * smart card is muted.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE = 14;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * smart card is invalid.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID = 15;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * of a geographical blackout.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT = 16;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * CAS system is rebooting.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING = 17;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * of unknown CAS error.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN = VIDEO_UNAVAILABLE_REASON_END;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 629dc7c..7e1f44c 100755
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -17,6 +17,7 @@
 package android.media.tv;
 
 import android.annotation.FloatRange;
+import android.annotation.IntDef;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -58,6 +59,8 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -96,6 +99,53 @@
     public static final String SERVICE_META_DATA = "android.media.tv.input";
 
     /**
+     * Prioirity hint from use case types.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "PRIORITY_HINT_USE_CASE_TYPE_",
+        value = {PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND, PRIORITY_HINT_USE_CASE_TYPE_SCAN,
+            PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, PRIORITY_HINT_USE_CASE_TYPE_LIVE,
+            PRIORITY_HINT_USE_CASE_TYPE_RECORD})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PriorityHintUseCaseType {}
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(int, String , int)}:
+     * Background.
+     * TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(int, String , int)}:
+     * Scan.
+     * TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_SCAN = 200;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(int, String , int)}:
+     * Playback.
+     * TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(int, String , int)}:
+     * Live.
+     * TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(int, String , int)}:
+     * Record.
+     * TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_RECORD = 500;
+
+    /**
      * Handler instance to handle request from TV Input Manager Service. Should be run in the main
      * looper to be synchronously run with {@code Session.mHandler}.
      */
diff --git a/media/java/android/media/tv/tuner/DemuxCapabilities.java b/media/java/android/media/tv/tuner/DemuxCapabilities.java
index 83abf86..2c08e5b 100644
--- a/media/java/android/media/tv/tuner/DemuxCapabilities.java
+++ b/media/java/android/media/tv/tuner/DemuxCapabilities.java
@@ -16,9 +16,12 @@
 
 package android.media.tv.tuner;
 
+import android.annotation.BytesLong;
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.Size;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.filter.Filter;
 import android.media.tv.tuner.filter.FilterConfiguration;
 
 import java.lang.annotation.Retention;
@@ -29,46 +32,47 @@
  *
  * @hide
  */
+@SystemApi
 public class DemuxCapabilities {
 
     /** @hide */
     @IntDef(flag = true, value = {
-            FilterConfiguration.FILTER_TYPE_TS,
-            FilterConfiguration.FILTER_TYPE_MMTP,
-            FilterConfiguration.FILTER_TYPE_IP,
-            FilterConfiguration.FILTER_TYPE_TLV,
-            FilterConfiguration.FILTER_TYPE_ALP
+            Filter.TYPE_TS,
+            Filter.TYPE_MMTP,
+            Filter.TYPE_IP,
+            Filter.TYPE_TLV,
+            Filter.TYPE_ALP
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface FilterCapabilities {}
 
-    private final int mNumDemux;
-    private final int mNumRecord;
-    private final int mNumPlayback;
-    private final int mNumTsFilter;
-    private final int mNumSectionFilter;
-    private final int mNumAudioFilter;
-    private final int mNumVideoFilter;
-    private final int mNumPesFilter;
-    private final int mNumPcrFilter;
-    private final int mNumBytesInSectionFilter;
+    private final int mDemuxCount;
+    private final int mRecordCount;
+    private final int mPlaybackCount;
+    private final int mTsFilterCount;
+    private final int mSectionFilterCount;
+    private final int mAudioFilterCount;
+    private final int mVideoFilterCount;
+    private final int mPesFilterCount;
+    private final int mPcrFilterCount;
+    private final long mSectionFilterLength;
     private final int mFilterCaps;
     private final int[] mLinkCaps;
 
     // Used by JNI
-    private DemuxCapabilities(int numDemux, int numRecord, int numPlayback, int numTsFilter,
-            int numSectionFilter, int numAudioFilter, int numVideoFilter, int numPesFilter,
-            int numPcrFilter, int numBytesInSectionFilter, int filterCaps, int[] linkCaps) {
-        mNumDemux = numDemux;
-        mNumRecord = numRecord;
-        mNumPlayback = numPlayback;
-        mNumTsFilter = numTsFilter;
-        mNumSectionFilter = numSectionFilter;
-        mNumAudioFilter = numAudioFilter;
-        mNumVideoFilter = numVideoFilter;
-        mNumPesFilter = numPesFilter;
-        mNumPcrFilter = numPcrFilter;
-        mNumBytesInSectionFilter = numBytesInSectionFilter;
+    private DemuxCapabilities(int demuxCount, int recordCount, int playbackCount, int tsFilterCount,
+            int sectionFilterCount, int audioFilterCount, int videoFilterCount, int pesFilterCount,
+            int pcrFilterCount, long sectionFilterLength, int filterCaps, int[] linkCaps) {
+        mDemuxCount = demuxCount;
+        mRecordCount = recordCount;
+        mPlaybackCount = playbackCount;
+        mTsFilterCount = tsFilterCount;
+        mSectionFilterCount = sectionFilterCount;
+        mAudioFilterCount = audioFilterCount;
+        mVideoFilterCount = videoFilterCount;
+        mPesFilterCount = pesFilterCount;
+        mPcrFilterCount = pcrFilterCount;
+        mSectionFilterLength = sectionFilterLength;
         mFilterCaps = filterCaps;
         mLinkCaps = linkCaps;
     }
@@ -76,62 +80,63 @@
     /**
      * Gets total number of demuxes.
      */
-    public int getNumDemux() {
-        return mNumDemux;
+    public int getDemuxCount() {
+        return mDemuxCount;
     }
     /**
      * Gets max number of recordings at a time.
      */
-    public int getNumRecord() {
-        return mNumRecord;
+    public int getRecordCount() {
+        return mRecordCount;
     }
     /**
      * Gets max number of playbacks at a time.
      */
-    public int getNumPlayback() {
-        return mNumPlayback;
+    public int getPlaybackCount() {
+        return mPlaybackCount;
     }
     /**
      * Gets number of TS filters.
      */
-    public int getNumTsFilter() {
-        return mNumTsFilter;
+    public int getTsFilterCount() {
+        return mTsFilterCount;
     }
     /**
      * Gets number of section filters.
      */
-    public int getNumSectionFilter() {
-        return mNumSectionFilter;
+    public int getSectionFilterCount() {
+        return mSectionFilterCount;
     }
     /**
      * Gets number of audio filters.
      */
-    public int getNumAudioFilter() {
-        return mNumAudioFilter;
+    public int getAudioFilterCount() {
+        return mAudioFilterCount;
     }
     /**
      * Gets number of video filters.
      */
-    public int getNumVideoFilter() {
-        return mNumVideoFilter;
+    public int getVideoFilterCount() {
+        return mVideoFilterCount;
     }
     /**
      * Gets number of PES filters.
      */
-    public int getNumPesFilter() {
-        return mNumPesFilter;
+    public int getPesFilterCount() {
+        return mPesFilterCount;
     }
     /**
      * Gets number of PCR filters.
      */
-    public int getNumPcrFilter() {
-        return mNumPcrFilter;
+    public int getPcrFilterCount() {
+        return mPcrFilterCount;
     }
     /**
      * Gets number of bytes in the mask of a section filter.
      */
-    public int getNumBytesInSectionFilter() {
-        return mNumBytesInSectionFilter;
+    @BytesLong
+    public long getSectionFilterLength() {
+        return mSectionFilterLength;
     }
     /**
      * Gets filter capabilities in bit field.
diff --git a/media/java/android/media/tv/tuner/Descrambler.java b/media/java/android/media/tv/tuner/Descrambler.java
index 23016e9..f46d3ce 100644
--- a/media/java/android/media/tv/tuner/Descrambler.java
+++ b/media/java/android/media/tv/tuner/Descrambler.java
@@ -18,7 +18,8 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.filter.Filter;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -32,6 +33,7 @@
  *
  * @hide
  */
+@SystemApi
 public class Descrambler implements AutoCloseable {
     /** @hide */
     @IntDef(prefix = "PID_TYPE_", value = {PID_TYPE_T, PID_TYPE_MMTP})
@@ -55,6 +57,7 @@
     private native int nativeSetKeyToken(byte[] keyToken);
     private native int nativeClose();
 
+    // Called by JNI code
     private Descrambler() {}
 
     /**
diff --git a/media/java/android/media/tv/tuner/FrontendSettings.java b/media/java/android/media/tv/tuner/FrontendSettings.java
index ad8422c..7f9b982 100644
--- a/media/java/android/media/tv/tuner/FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/FrontendSettings.java
@@ -16,33 +16,10 @@
 
 package android.media.tv.tuner;
 
-import android.annotation.SystemApi;
-
 /**
  * Frontend settings for tune and scan operations.
+ * TODO: remove
  * @hide
  */
-@SystemApi
 public abstract class FrontendSettings {
-    private final int mFrequency;
-
-    /** @hide */
-    public FrontendSettings(int frequency) {
-        mFrequency = frequency;
-    }
-
-    /**
-     * Returns the frontend type.
-     */
-    public abstract int getType();
-
-    /**
-     * Gets the frequency setting.
-     *
-     * @return the frequency in Hz.
-     */
-    public final int getFrequency() {
-        return mFrequency;
-    }
-
 }
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index a9a15d9..a8d2cba 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -126,25 +126,21 @@
 
     /**
      * Outgoing Diseqc message overflow.
-     * @hide
      */
     public static final int EVENT_TYPE_DISEQC_RX_OVERFLOW =
             Constants.LnbEventType.DISEQC_RX_OVERFLOW;
     /**
      * Outgoing Diseqc message isn't delivered on time.
-     * @hide
      */
     public static final int EVENT_TYPE_DISEQC_RX_TIMEOUT =
             Constants.LnbEventType.DISEQC_RX_TIMEOUT;
     /**
      * Incoming Diseqc message has parity error.
-     * @hide
      */
     public static final int EVENT_TYPE_DISEQC_RX_PARITY_ERROR =
             Constants.LnbEventType.DISEQC_RX_PARITY_ERROR;
     /**
      * LNB is overload.
-     * @hide
      */
     public static final int EVENT_TYPE_LNB_OVERLOAD = Constants.LnbEventType.LNB_OVERLOAD;
 
@@ -162,8 +158,7 @@
         mId = id;
     }
 
-    /** @hide */
-    public void setCallback(@Nullable LnbCallback callback) {
+    void setCallback(@Nullable LnbCallback callback) {
         mCallback = callback;
         if (mCallback == null) {
             return;
diff --git a/media/java/android/media/tv/tuner/LnbCallback.java b/media/java/android/media/tv/tuner/LnbCallback.java
index 5155f60..7862470 100644
--- a/media/java/android/media/tv/tuner/LnbCallback.java
+++ b/media/java/android/media/tv/tuner/LnbCallback.java
@@ -17,6 +17,8 @@
 package android.media.tv.tuner;
 
 
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.media.tv.tuner.Lnb.EventType;
 
 /**
@@ -24,6 +26,7 @@
  *
  * @hide
  */
+@SystemApi
 public interface LnbCallback {
     /**
      * Invoked when there is a LNB event.
@@ -37,5 +40,5 @@
      * Equipment Control) message which is specified by EUTELSAT Bus Functional
      * Specification Version 4.2.
      */
-    void onDiseqcMessage(byte[] diseqcMessage);
+    void onDiseqcMessage(@NonNull byte[] diseqcMessage);
 }
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 490f938..62ab2c9 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -23,18 +23,20 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.Context;
-import android.media.tv.tuner.TunerConstants.FilterStatus;
 import android.media.tv.tuner.TunerConstants.Result;
-import android.media.tv.tuner.dvr.Dvr;
-import android.media.tv.tuner.dvr.DvrCallback;
-import android.media.tv.tuner.dvr.DvrSettings;
+import android.media.tv.tuner.dvr.DvrPlayback;
+import android.media.tv.tuner.dvr.DvrRecorder;
+import android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener;
+import android.media.tv.tuner.dvr.OnRecordStatusChangedListener;
+import android.media.tv.tuner.filter.Filter;
 import android.media.tv.tuner.filter.Filter.Subtype;
 import android.media.tv.tuner.filter.Filter.Type;
-import android.media.tv.tuner.filter.FilterEvent;
+import android.media.tv.tuner.filter.FilterCallback;
 import android.media.tv.tuner.filter.TimeFilter;
-import android.media.tv.tuner.frontend.FrontendCallback;
 import android.media.tv.tuner.frontend.FrontendInfo;
+import android.media.tv.tuner.frontend.FrontendSettings;
 import android.media.tv.tuner.frontend.FrontendStatus;
+import android.media.tv.tuner.frontend.OnTuneEventListener;
 import android.media.tv.tuner.frontend.ScanCallback;
 import android.os.Handler;
 import android.os.Looper;
@@ -57,7 +59,6 @@
     private static final String TAG = "MediaTvTuner";
     private static final boolean DEBUG = false;
 
-    private static final int MSG_ON_FRONTEND_EVENT = 1;
     private static final int MSG_ON_FILTER_EVENT = 2;
     private static final int MSG_ON_FILTER_STATUS = 3;
     private static final int MSG_ON_LNB_EVENT = 4;
@@ -76,6 +77,10 @@
     private List<Integer> mLnbIds;
     private Lnb mLnb;
     @Nullable
+    private OnTuneEventListener mOnTuneEventListener;
+    @Nullable
+    private Executor mOnTunerEventExecutor;
+    @Nullable
     private ScanCallback mScanCallback;
     @Nullable
     private Executor mScanCallbackExecutor;
@@ -162,34 +167,13 @@
 
     private native Descrambler nativeOpenDescrambler();
 
-    private native Dvr nativeOpenDvr(int type, long bufferSize);
+    private native DvrRecorder nativeOpenDvrRecorder(long bufferSize);
+    private native DvrPlayback nativeOpenDvrPlayback(long bufferSize);
 
     private static native DemuxCapabilities nativeGetDemuxCapabilities();
 
 
     /**
-     * Callback interface for receiving information from the corresponding filters.
-     * TODO: remove
-     */
-    public interface FilterCallback {
-        /**
-         * Invoked when there are filter events.
-         *
-         * @param filter the corresponding filter which sent the events.
-         * @param events the filter events sent from the filter.
-         */
-        void onFilterEvent(@NonNull Filter filter, @NonNull FilterEvent[] events);
-        /**
-         * Invoked when filter status changed.
-         *
-         * @param filter the corresponding filter whose status is changed.
-         * @param status the new status of the filter.
-         */
-        void onFilterStatusChanged(@NonNull Filter filter, @FilterStatus int status);
-    }
-
-
-    /**
      * Listener for resource lost.
      *
      * @hide
@@ -222,15 +206,10 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_ON_FRONTEND_EVENT:
-                    if (mFrontend != null && mFrontend.mCallback != null) {
-                        mFrontend.mCallback.onEvent(msg.arg1);
-                    }
-                    break;
                 case MSG_ON_FILTER_STATUS: {
                     Filter filter = (Filter) msg.obj;
-                    if (filter.mCallback != null) {
-                        filter.mCallback.onFilterStatusChanged(filter, msg.arg1);
+                    if (filter.getCallback() != null) {
+                        filter.getCallback().onFilterStatusChanged(filter, msg.arg1);
                     }
                     break;
                 }
@@ -242,7 +221,6 @@
 
     private class Frontend {
         private int mId;
-        private FrontendCallback mCallback;
 
         private Frontend(int id) {
             mId = id;
@@ -250,13 +228,59 @@
     }
 
     /**
-     * Tunes the frontend to the settings given.
+     * Listens for tune events.
      *
-     * @return result status of tune operation.
+     * <p>
+     * Tuner events are started when {@link #tune(FrontendSettings)} is called and end when {@link
+     * #stopTune()} is called.
+     *
+     * @param eventListener receives tune events.
      * @throws SecurityException if the caller does not have appropriate permissions.
-     * TODO: add result constants or throw exceptions.
+     * @see #tune(FrontendSettings)
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+    public void setOnTuneEventListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OnTuneEventListener eventListener) {
+        TunerUtils.checkTunerPermission(mContext);
+        mOnTuneEventListener = eventListener;
+        mOnTunerEventExecutor = executor;
+    }
+
+    /**
+     * Clears the {@link OnTuneEventListener} and its associated {@link Executor}.
+     *
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     * @see #setOnTuneEventListener(Executor, OnTuneEventListener)
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+    public void clearOnTuneEventListener() {
+        TunerUtils.checkTunerPermission(mContext);
+        mOnTuneEventListener = null;
+        mOnTunerEventExecutor = null;
+
+    }
+
+    /**
+     * Tunes the frontend to using the settings given.
+     *
+     * <p>
+     * This locks the frontend to a frequency by providing signal
+     * delivery information. If previous tuning isn't completed, this stop the previous tuning, and
+     * start a new tuning.
+     *
+     * <p>
+     * Tune is an async call, with {@link OnTuneEventListener#LOCKED LOCKED} and {@link
+     * OnTuneEventListener#NO_SIGNAL NO_SIGNAL} events sent to the {@link OnTuneEventListener}
+     * specified in {@link #setOnTuneEventListener(Executor, OnTuneEventListener)}.
+     *
+     * @param settings Signal delivery information the frontend uses to
+     *                 search and lock the signal.
+     * @return result status of tune operation.
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     * @see #setOnTuneEventListener(Executor, OnTuneEventListener)
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+    @Result
     public int tune(@NonNull FrontendSettings settings) {
         TunerUtils.checkTunerPermission(mContext);
         return nativeTune(settings.getType(), settings);
@@ -269,8 +293,6 @@
      * will be sent to attached filters.
      *
      * @return result status of the operation.
-     *
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Result
@@ -289,10 +311,10 @@
      * @throws SecurityException     if the caller does not have appropriate permissions.
      * @throws IllegalStateException if {@code scan} is called again before {@link #stopScan()} is
      *                               called.
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
-    public int scan(@NonNull FrontendSettings settings, @ScanCallback.ScanType int scanType,
+    @Result
+    public int scan(@NonNull FrontendSettings settings, @TunerConstants.ScanType int scanType,
             @NonNull @CallbackExecutor Executor executor, @NonNull ScanCallback scanCallback) {
         TunerUtils.checkTunerPermission(mContext);
         if (mScanCallback != null || mScanCallbackExecutor != null) {
@@ -315,7 +337,6 @@
      * If the method completes successfully, the frontend stopped previous scanning.
      *
      * @throws SecurityException if the caller does not have appropriate permissions.
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Result
@@ -501,23 +522,12 @@
     }
 
     private void onFrontendEvent(int eventType) {
-        if (mHandler != null) {
-            mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_FRONTEND_EVENT, eventType, 0));
+        if (mOnTunerEventExecutor != null && mOnTuneEventListener != null) {
+            mOnTunerEventExecutor.execute(() -> mOnTuneEventListener.onTuneEvent(eventType));
         }
     }
 
     /**
-     * Tuner data filter.
-     *
-     * <p> This class is used to filter wanted data according to the filter's configuration.
-     * TODO: remove
-     */
-    public class Filter {
-        FilterCallback mCallback;
-        private Filter() {}
-    }
-
-    /**
      * Opens a filter object based on the given types and buffer size.
      *
      * @param mainType the main type of the filter.
@@ -528,8 +538,6 @@
      * executor is used if it's {@code null}.
      * @param cb the callback to receive notifications from filter.
      * @return the opened filter. {@code null} if the operation failed.
-     *
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Nullable
@@ -540,7 +548,7 @@
         Filter filter = nativeOpenFilter(
                 mainType, TunerUtils.getFilterSubtype(mainType, subType), bufferSize);
         if (filter != null) {
-            filter.mCallback = cb;
+            filter.setCallback(cb);
             if (mHandler == null) {
                 mHandler = createEventHandler();
             }
@@ -555,12 +563,11 @@
      * executor is used if it's {@code null}.
      * @param cb the callback to receive notifications from LNB.
      * @return the opened LNB object. {@code null} if the operation failed.
-     *
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Nullable
-    public Lnb openLnb(@CallbackExecutor @Nullable Executor executor, LnbCallback cb) {
+    public Lnb openLnb(@CallbackExecutor @Nullable Executor executor, @Nullable LnbCallback cb) {
+        TunerUtils.checkTunerPermission(mContext);
         return openLnbByName(null, executor, cb);
     }
 
@@ -572,18 +579,26 @@
      * executor is used if it's {@code null}.
      * @param cb the callback to receive notifications from LNB.
      * @return the opened LNB object. {@code null} if the operation failed.
-     *
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Nullable
     public Lnb openLnbByName(@Nullable String name, @CallbackExecutor @Nullable Executor executor,
-            LnbCallback cb) {
+            @NonNull LnbCallback cb) {
         TunerUtils.checkTunerPermission(mContext);
         // TODO: use resource manager to get LNB ID.
         return new Lnb(0);
     }
 
+    /**
+     * Open a time filter object.
+     *
+     * @return the opened time filter object. {@code null} if the operation failed.
+     */
+    @Nullable
+    public TimeFilter openTimeFilter() {
+        return nativeOpenTimeFilter();
+    }
+
     private List<Integer> getLnbIds() {
         mLnbIds = nativeGetLnbIds();
         return mLnbIds;
@@ -632,24 +647,44 @@
     }
 
     /**
-     * Open a DVR (Digital Video Record) instance.
+     * Open a DVR (Digital Video Record) recorder instance.
      *
-     * @param type the DVR type to be opened.
      * @param bufferSize the buffer size of the output in bytes. It's used to hold output data of
      * the attached filters.
      * @param executor the executor on which callback will be invoked. The default event handler
      * executor is used if it's {@code null}.
-     * @param cb the callback to receive notifications from DVR.
-     * @return the opened DVR object. {@code null} if the operation failed.
-     *
-     * @hide
+     * @param l the listener to receive notifications from DVR recorder.
+     * @return the opened DVR recorder object. {@code null} if the operation failed.
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Nullable
-    public Dvr openDvr(@DvrSettings.Type int type, @BytesLong long bufferSize,
-            @CallbackExecutor @Nullable Executor executor, DvrCallback cb) {
+    public DvrRecorder openDvrRecorder(
+            @BytesLong long bufferSize,
+            @CallbackExecutor @Nullable Executor executor,
+            @Nullable OnRecordStatusChangedListener l) {
         TunerUtils.checkTunerPermission(mContext);
-        Dvr dvr = nativeOpenDvr(type, bufferSize);
+        DvrRecorder dvr = nativeOpenDvrRecorder(bufferSize);
+        return dvr;
+    }
+
+    /**
+     * Open a DVR (Digital Video Record) playback instance.
+     *
+     * @param bufferSize the buffer size of the output in bytes. It's used to hold output data of
+     * the attached filters.
+     * @param executor the executor on which callback will be invoked. The default event handler
+     * executor is used if it's {@code null}.
+     * @param l the listener to receive notifications from DVR recorder.
+     * @return the opened DVR playback object. {@code null} if the operation failed.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+    @Nullable
+    public DvrPlayback openDvrPlayback(
+            @BytesLong long bufferSize,
+            @CallbackExecutor @Nullable Executor executor,
+            @Nullable OnPlaybackStatusChangedListener l) {
+        TunerUtils.checkTunerPermission(mContext);
+        DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize);
         return dvr;
     }
 }
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
index 5a0c91f..c030619 100644
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ b/media/java/android/media/tv/tuner/TunerConstants.java
@@ -47,61 +47,27 @@
      */
     public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
 
-
     /** @hide */
-    @IntDef(prefix = "FRONTEND_EVENT_TYPE_",
-            value = {FRONTEND_EVENT_TYPE_LOCKED, FRONTEND_EVENT_TYPE_NO_SIGNAL,
-                    FRONTEND_EVENT_TYPE_LOST_LOCK})
+    @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
     @Retention(RetentionPolicy.SOURCE)
-    public @interface FrontendEventType {}
+    public @interface ScanType {}
     /**
-     * Frontend locked.
-     * @hide
+     * Scan type undefined.
      */
-    public static final int FRONTEND_EVENT_TYPE_LOCKED = Constants.FrontendEventType.LOCKED;
+    public static final int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
     /**
-     * No signal detected.
-     * @hide
-     */
-    public static final int FRONTEND_EVENT_TYPE_NO_SIGNAL = Constants.FrontendEventType.NO_SIGNAL;
-    /**
-     * Frontend lock lost.
-     * @hide
-     */
-    public static final int FRONTEND_EVENT_TYPE_LOST_LOCK = Constants.FrontendEventType.LOST_LOCK;
-
-
-    /** @hide */
-    @IntDef(flag = true, prefix = "FILTER_STATUS_", value = {FILTER_STATUS_DATA_READY,
-            FILTER_STATUS_LOW_WATER, FILTER_STATUS_HIGH_WATER, FILTER_STATUS_OVERFLOW})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FilterStatus {}
-
-    /**
-     * The status of a filter that the data in the filter buffer is ready to be read.
-     */
-    public static final int FILTER_STATUS_DATA_READY = Constants.DemuxFilterStatus.DATA_READY;
-    /**
-     * The status of a filter that the amount of available data in the filter buffer is at low
-     * level.
+     * Scan type auto.
      *
-     * The value is set to 25 percent of the buffer size by default. It can be changed when
-     * configuring the filter.
+     * <p> Tuner will send {@link #onLocked}
      */
-    public static final int FILTER_STATUS_LOW_WATER = Constants.DemuxFilterStatus.LOW_WATER;
+    public static final int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
     /**
-     * The status of a filter that the amount of available data in the filter buffer is at high
-     * level.
-     * The value is set to 75 percent of the buffer size by default. It can be changed when
-     * configuring the filter.
+     * Blind scan.
+     *
+     * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
+     * implementation specific range.
      */
-    public static final int FILTER_STATUS_HIGH_WATER = Constants.DemuxFilterStatus.HIGH_WATER;
-    /**
-     * The status of a filter that the filter buffer is full and newly filtered data is being
-     * discarded.
-     */
-    public static final int FILTER_STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
-
+    public static final int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -125,7 +91,6 @@
      */
     public static final int INDEX_TYPE_SC_HEVC = Constants.DemuxRecordScIndexType.SC_HEVC;
 
-
     /**
      * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
      * according to ISO/IEC 13818-1.
@@ -138,22 +103,18 @@
 
     /**
      * SC index for a new I-frame.
-     * @hide
      */
     public static final int SC_INDEX_I_FRAME = Constants.DemuxScIndex.I_FRAME;
     /**
      * SC index for a new P-frame.
-     * @hide
      */
     public static final int SC_INDEX_P_FRAME = Constants.DemuxScIndex.P_FRAME;
     /**
      * SC index for a new B-frame.
-     * @hide
      */
     public static final int SC_INDEX_B_FRAME = Constants.DemuxScIndex.B_FRAME;
     /**
      * SC index for a new sequence.
-     * @hide
      */
     public static final int SC_INDEX_SEQUENCE = Constants.DemuxScIndex.SEQUENCE;
 
@@ -173,47 +134,39 @@
 
     /**
      * SC HEVC index SPS.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SPS = Constants.DemuxScHevcIndex.SPS;
     /**
      * SC HEVC index AUD.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_AUD = Constants.DemuxScHevcIndex.AUD;
     /**
      * SC HEVC index SLICE_CE_BLA_W_LP.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SLICE_CE_BLA_W_LP =
             Constants.DemuxScHevcIndex.SLICE_CE_BLA_W_LP;
     /**
      * SC HEVC index SLICE_BLA_W_RADL.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SLICE_BLA_W_RADL =
             Constants.DemuxScHevcIndex.SLICE_BLA_W_RADL;
     /**
      * SC HEVC index SLICE_BLA_N_LP.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SLICE_BLA_N_LP =
             Constants.DemuxScHevcIndex.SLICE_BLA_N_LP;
     /**
      * SC HEVC index SLICE_IDR_W_RADL.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SLICE_IDR_W_RADL =
             Constants.DemuxScHevcIndex.SLICE_IDR_W_RADL;
     /**
      * SC HEVC index SLICE_IDR_N_LP.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SLICE_IDR_N_LP =
             Constants.DemuxScHevcIndex.SLICE_IDR_N_LP;
     /**
      * SC HEVC index SLICE_TRAIL_CRA.
-     * @hide
      */
     public static final int SC_HEVC_INDEX_SLICE_TRAIL_CRA =
             Constants.DemuxScHevcIndex.SLICE_TRAIL_CRA;
diff --git a/media/java/android/media/tv/tuner/dvr/Dvr.java b/media/java/android/media/tv/tuner/dvr/Dvr.java
index a17773c..4183e3b 100644
--- a/media/java/android/media/tv/tuner/dvr/Dvr.java
+++ b/media/java/android/media/tv/tuner/dvr/Dvr.java
@@ -16,12 +16,12 @@
 
 package android.media.tv.tuner.dvr;
 
-import android.annotation.BytesLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.Tuner.Filter;
 import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.filter.Filter;
 import android.os.ParcelFileDescriptor;
 
 import java.lang.annotation.Retention;
@@ -33,40 +33,26 @@
  *
  * @hide
  */
-public class Dvr {
+@SystemApi
+public class Dvr implements AutoCloseable {
+
     /** @hide */
+    @IntDef(prefix = "TYPE_", value = {TYPE_RECORD, TYPE_PLAYBACK})
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "PLAYBACK_STATUS_",
-            value = {PLAYBACK_STATUS_EMPTY, PLAYBACK_STATUS_ALMOST_EMPTY,
-                    PLAYBACK_STATUS_ALMOST_FULL, PLAYBACK_STATUS_FULL})
-    @interface PlaybackStatus {}
+    public @interface Type {}
 
     /**
-     * The space of the playback is empty.
+     * DVR for recording.
      */
-    public static final int PLAYBACK_STATUS_EMPTY = Constants.PlaybackStatus.SPACE_EMPTY;
+    public static final int TYPE_RECORD = Constants.DvrType.RECORD;
     /**
-     * The space of the playback is almost empty.
-     *
-     * <p> the threshold is set in {@link DvrSettings}.
+     * DVR for playback of recorded programs.
      */
-    public static final int PLAYBACK_STATUS_ALMOST_EMPTY =
-            Constants.PlaybackStatus.SPACE_ALMOST_EMPTY;
-    /**
-     * The space of the playback is almost full.
-     *
-     * <p> the threshold is set in {@link DvrSettings}.
-     */
-    public static final int PLAYBACK_STATUS_ALMOST_FULL =
-            Constants.PlaybackStatus.SPACE_ALMOST_FULL;
-    /**
-     * The space of the playback is full.
-     */
-    public static final int PLAYBACK_STATUS_FULL = Constants.PlaybackStatus.SPACE_FULL;
+    public static final int TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
 
 
-    private long mNativeContext;
-    private DvrCallback mCallback;
+    final int mType;
+    long mNativeContext;
 
     private native int nativeAttachFilter(Filter filter);
     private native int nativeDetachFilter(Filter filter);
@@ -76,12 +62,10 @@
     private native int nativeFlushDvr();
     private native int nativeClose();
     private native void nativeSetFileDescriptor(int fd);
-    private native int nativeRead(long size);
-    private native int nativeRead(byte[] bytes, long offset, long size);
-    private native int nativeWrite(long size);
-    private native int nativeWrite(byte[] bytes, long offset, long size);
 
-    private Dvr() {}
+    protected Dvr(int type) {
+        mType = type;
+    }
 
     /**
      * Attaches a filter to DVR interface for recording.
@@ -154,12 +138,9 @@
 
     /**
      * Closes the DVR instance to release resources.
-     *
-     * @return result status of the operation.
      */
-    @Result
-    public int close() {
-        return nativeClose();
+    public void close() {
+        nativeClose();
     }
 
     /**
@@ -171,51 +152,8 @@
         nativeSetFileDescriptor(fd.getFd());
     }
 
-    /**
-     * Reads data from the file for DVR playback.
-     *
-     * @param size the maximum number of bytes to read.
-     * @return the number of bytes read.
-     */
-    public int read(@BytesLong long size) {
-        return nativeRead(size);
-    }
-
-    /**
-     * Reads data from the buffer for DVR playback and copies to the given byte array.
-     *
-     * @param bytes the byte array to store the data.
-     * @param offset the index of the first byte in {@code bytes} to copy to.
-     * @param size the maximum number of bytes to read.
-     * @return the number of bytes read.
-     */
-    public int read(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) {
-        if (size + offset > bytes.length) {
-            throw new ArrayIndexOutOfBoundsException(
-                    "Array length=" + bytes.length + ", offset=" + offset + ", size=" + size);
-        }
-        return nativeRead(bytes, offset, size);
-    }
-
-    /**
-     * Writes recording data to file.
-     *
-     * @param size the maximum number of bytes to write.
-     * @return the number of bytes written.
-     */
-    public int write(@BytesLong long size) {
-        return nativeWrite(size);
-    }
-
-    /**
-     * Writes recording data to buffer.
-     *
-     * @param bytes the byte array stores the data to be written to DVR.
-     * @param offset the index of the first byte in {@code bytes} to be written to DVR.
-     * @param size the maximum number of bytes to write.
-     * @return the number of bytes written.
-     */
-    public int write(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) {
-        return nativeWrite(bytes, offset, size);
+    @Type
+    int getType() {
+        return mType;
     }
 }
diff --git a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
new file mode 100644
index 0000000..eb31574
--- /dev/null
+++ b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner.dvr;
+
+import android.annotation.BytesLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Digital Video Record (DVR) class which provides playback control on Demux's input buffer.
+ *
+ * <p>It's used to play recorded programs.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvrPlayback extends Dvr {
+
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "PLAYBACK_STATUS_",
+            value = {PLAYBACK_STATUS_EMPTY, PLAYBACK_STATUS_ALMOST_EMPTY,
+                    PLAYBACK_STATUS_ALMOST_FULL, PLAYBACK_STATUS_FULL})
+    @interface PlaybackStatus {}
+
+    /**
+     * The space of the playback is empty.
+     */
+    public static final int PLAYBACK_STATUS_EMPTY = Constants.PlaybackStatus.SPACE_EMPTY;
+    /**
+     * The space of the playback is almost empty.
+     *
+     * <p> the threshold is set in {@link DvrSettings}.
+     */
+    public static final int PLAYBACK_STATUS_ALMOST_EMPTY =
+            Constants.PlaybackStatus.SPACE_ALMOST_EMPTY;
+    /**
+     * The space of the playback is almost full.
+     *
+     * <p> the threshold is set in {@link DvrSettings}.
+     */
+    public static final int PLAYBACK_STATUS_ALMOST_FULL =
+            Constants.PlaybackStatus.SPACE_ALMOST_FULL;
+    /**
+     * The space of the playback is full.
+     */
+    public static final int PLAYBACK_STATUS_FULL = Constants.PlaybackStatus.SPACE_FULL;
+
+
+
+    private native long nativeRead(long size);
+    private native long nativeRead(byte[] bytes, long offset, long size);
+
+    private DvrPlayback() {
+        super(Dvr.TYPE_PLAYBACK);
+    }
+
+
+    /**
+     * Reads data from the file for DVR playback.
+     *
+     * @param size the maximum number of bytes to read.
+     * @return the number of bytes read.
+     */
+    @BytesLong
+    public long read(@BytesLong long size) {
+        return nativeRead(size);
+    }
+
+    /**
+     * Reads data from the buffer for DVR playback and copies to the given byte array.
+     *
+     * @param bytes the byte array to store the data.
+     * @param offset the index of the first byte in {@code bytes} to copy to.
+     * @param size the maximum number of bytes to read.
+     * @return the number of bytes read.
+     */
+    @BytesLong
+    public long read(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) {
+        if (size + offset > bytes.length) {
+            throw new ArrayIndexOutOfBoundsException(
+                    "Array length=" + bytes.length + ", offset=" + offset + ", size=" + size);
+        }
+        return nativeRead(bytes, offset, size);
+    }
+}
diff --git a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
new file mode 100644
index 0000000..3128ca5
--- /dev/null
+++ b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner.dvr;
+
+import android.annotation.BytesLong;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Digital Video Record (DVR) recorder class which provides record control on Demux's output buffer.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvrRecorder extends Dvr {
+    private native long nativeWrite(long size);
+    private native long nativeWrite(byte[] bytes, long offset, long size);
+
+    private DvrRecorder() {
+        super(Dvr.TYPE_RECORD);
+    }
+
+    /**
+     * Writes recording data to file.
+     *
+     * @param size the maximum number of bytes to write.
+     * @return the number of bytes written.
+     */
+    @BytesLong
+    public long write(@BytesLong long size) {
+        return nativeWrite(size);
+    }
+
+    /**
+     * Writes recording data to buffer.
+     *
+     * @param bytes the byte array stores the data to be written to DVR.
+     * @param offset the index of the first byte in {@code bytes} to be written to DVR.
+     * @param size the maximum number of bytes to write.
+     * @return the number of bytes written.
+     */
+    @BytesLong
+    public long write(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) {
+        return nativeWrite(bytes, offset, size);
+    }
+}
diff --git a/media/java/android/media/tv/tuner/dvr/DvrSettings.java b/media/java/android/media/tv/tuner/dvr/DvrSettings.java
index 49e875a..f9dc682 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrSettings.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrSettings.java
@@ -20,10 +20,11 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.FilterStatus;
 import android.media.tv.tuner.TunerUtils;
+import android.media.tv.tuner.filter.Filter;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -33,6 +34,7 @@
  *
  * @hide
  */
+@SystemApi
 public class DvrSettings {
 
     /** @hide */
@@ -59,40 +61,64 @@
     public static final int DATA_FORMAT_SHV_TLV = Constants.DataFormat.SHV_TLV;
 
 
-    /** @hide */
-    @IntDef(prefix = "TYPE_", value = {TYPE_RECORD, TYPE_PLAYBACK})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    /**
-     * DVR for recording.
-     */
-    public static final int TYPE_RECORD = Constants.DvrType.RECORD;
-    /**
-     * DVR for playback of recorded programs.
-     */
-    public static final int TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
-
-
-
+    @Filter.Status
     private final int mStatusMask;
+    @BytesLong
     private final long mLowThreshold;
+    @BytesLong
     private final long mHighThreshold;
+    @BytesLong
     private final long mPacketSize;
-
     @DataFormat
     private final int mDataFormat;
-    @Type
-    private final int mType;
 
-    private DvrSettings(int statusMask, long lowThreshold, long highThreshold, long packetSize,
-            @DataFormat int dataFormat, @Type int type) {
+    private DvrSettings(@Filter.Status int statusMask, @BytesLong long lowThreshold,
+            @BytesLong long highThreshold, @BytesLong long packetSize, @DataFormat int dataFormat) {
         mStatusMask = statusMask;
         mLowThreshold = lowThreshold;
         mHighThreshold = highThreshold;
         mPacketSize = packetSize;
         mDataFormat = dataFormat;
-        mType = type;
+    }
+
+    /**
+     * Gets status mask.
+     */
+    @Filter.Status
+    public int getStatusMask() {
+        return mStatusMask;
+    }
+
+    /**
+     * Gets low threshold in bytes.
+     */
+    @BytesLong
+    public long getLowThreshold() {
+        return mLowThreshold;
+    }
+
+    /**
+     * Sets high threshold in bytes.
+     */
+    @BytesLong
+    public long getHighThreshold() {
+        return mHighThreshold;
+    }
+
+    /**
+     * Gets packet size in bytes.
+     */
+    @BytesLong
+    public long getPacketSize() {
+        return mPacketSize;
+    }
+
+    /**
+     * Gets data format.
+     */
+    @DataFormat
+    public int getDataFormat() {
+        return mDataFormat;
     }
 
     /**
@@ -102,7 +128,7 @@
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @NonNull
-    public static Builder builder(Context context) {
+    public static Builder builder(@NonNull Context context) {
         TunerUtils.checkTunerPermission(context);
         return new Builder();
     }
@@ -117,14 +143,12 @@
         private long mPacketSize;
         @DataFormat
         private int mDataFormat;
-        @Type
-        private int mType;
 
         /**
          * Sets status mask.
          */
         @NonNull
-        public Builder setStatusMask(@FilterStatus int statusMask) {
+        public Builder setStatusMask(@Filter.Status int statusMask) {
             this.mStatusMask = statusMask;
             return this;
         }
@@ -166,21 +190,12 @@
         }
 
         /**
-         * Sets settings type.
-         */
-        @NonNull
-        public Builder setType(@Type int type) {
-            this.mType = type;
-            return this;
-        }
-
-        /**
          * Builds a {@link DvrSettings} object.
          */
         @NonNull
         public DvrSettings build() {
             return new DvrSettings(
-                    mStatusMask, mLowThreshold, mHighThreshold, mPacketSize, mDataFormat, mType);
+                    mStatusMask, mLowThreshold, mHighThreshold, mPacketSize, mDataFormat);
         }
     }
 }
diff --git a/media/java/android/media/tv/tuner/dvr/DvrCallback.java b/media/java/android/media/tv/tuner/dvr/OnPlaybackStatusChangedListener.java
similarity index 65%
rename from media/java/android/media/tv/tuner/dvr/DvrCallback.java
rename to media/java/android/media/tv/tuner/dvr/OnPlaybackStatusChangedListener.java
index ee0cfa7..a9a1779 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrCallback.java
+++ b/media/java/android/media/tv/tuner/dvr/OnPlaybackStatusChangedListener.java
@@ -16,21 +16,17 @@
 
 package android.media.tv.tuner.dvr;
 
-import android.media.tv.tuner.TunerConstants.FilterStatus;
-import android.media.tv.tuner.dvr.Dvr.PlaybackStatus;
+import android.annotation.SystemApi;
 
 /**
- * Callback interface for receiving information from DVR interfaces.
+ * Listener interface for receiving information from DVR playback.
  *
  * @hide
  */
-public interface DvrCallback {
-    /**
-     * Invoked when record status changed.
-     */
-    void onRecordStatusChanged(@FilterStatus int status);
+@SystemApi
+public interface OnPlaybackStatusChangedListener {
     /**
      * Invoked when playback status changed.
      */
-    void onPlaybackStatusChanged(@PlaybackStatus int status);
+    void onPlaybackStatusChanged(@DvrPlayback.PlaybackStatus int status);
 }
diff --git a/media/java/android/media/tv/tuner/dvr/DvrCallback.java b/media/java/android/media/tv/tuner/dvr/OnRecordStatusChangedListener.java
similarity index 65%
copy from media/java/android/media/tv/tuner/dvr/DvrCallback.java
copy to media/java/android/media/tv/tuner/dvr/OnRecordStatusChangedListener.java
index ee0cfa7..cb6ccab 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrCallback.java
+++ b/media/java/android/media/tv/tuner/dvr/OnRecordStatusChangedListener.java
@@ -16,21 +16,18 @@
 
 package android.media.tv.tuner.dvr;
 
-import android.media.tv.tuner.TunerConstants.FilterStatus;
-import android.media.tv.tuner.dvr.Dvr.PlaybackStatus;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.filter.Filter;
 
 /**
- * Callback interface for receiving information from DVR interfaces.
+ * Listener interface for receiving information from DVR recorder.
  *
  * @hide
  */
-public interface DvrCallback {
+@SystemApi
+public interface OnRecordStatusChangedListener {
     /**
      * Invoked when record status changed.
      */
-    void onRecordStatusChanged(@FilterStatus int status);
-    /**
-     * Invoked when playback status changed.
-     */
-    void onPlaybackStatusChanged(@PlaybackStatus int status);
+    void onRecordStatusChanged(@Filter.Status int status);
 }
diff --git a/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java
index fcca6a1..064ab80 100644
--- a/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
 import android.media.tv.tuner.TunerUtils;
@@ -28,8 +29,10 @@
 
 /**
  * Filter configuration for a ALP filter.
+ *
  * @hide
  */
+@SystemApi
 public class AlpFilterConfiguration extends FilterConfiguration {
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -57,7 +60,7 @@
     private final int mPacketType;
     private final int mLengthType;
 
-    public AlpFilterConfiguration(Settings settings, int packetType, int lengthType) {
+    private AlpFilterConfiguration(Settings settings, int packetType, int lengthType) {
         super(settings);
         mPacketType = packetType;
         mLengthType = lengthType;
@@ -65,7 +68,7 @@
 
     @Override
     public int getType() {
-        return FilterConfiguration.FILTER_TYPE_ALP;
+        return Filter.TYPE_ALP;
     }
 
     /**
diff --git a/media/java/android/media/tv/tuner/filter/AudioDescriptor.java b/media/java/android/media/tv/tuner/filter/AudioDescriptor.java
index c88c07f..7b1576a 100644
--- a/media/java/android/media/tv/tuner/filter/AudioDescriptor.java
+++ b/media/java/android/media/tv/tuner/filter/AudioDescriptor.java
@@ -16,11 +16,14 @@
 
 package android.media.tv.tuner.filter;
 
+import android.annotation.SystemApi;
+
 /**
  * Meta data from AD (Audio Descriptor) according to ETSI TS 101 154 V2.1.1.
  *
  * @hide
  */
+@SystemApi
 public class AudioDescriptor {
     private final byte mAdFade;
     private final byte mAdPan;
@@ -68,7 +71,7 @@
      *
      * <p>A single ASCII character version designator (here "1" indicates revision 1).
      */
-    public char getVersionTextTag() {
+    public char getAdVersionTextTag() {
         return mVersionTextTag;
     }
 
diff --git a/media/java/android/media/tv/tuner/filter/AvSettings.java b/media/java/android/media/tv/tuner/filter/AvSettings.java
index 93eaaa4..bf11893 100644
--- a/media/java/android/media/tv/tuner/filter/AvSettings.java
+++ b/media/java/android/media/tv/tuner/filter/AvSettings.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
@@ -26,6 +27,7 @@
  *
  * @hide
  */
+@SystemApi
 public class AvSettings extends Settings {
     private final boolean mIsPassthrough;
 
diff --git a/media/java/android/media/tv/tuner/filter/DownloadEvent.java b/media/java/android/media/tv/tuner/filter/DownloadEvent.java
index 591e4e5..9f97b61 100644
--- a/media/java/android/media/tv/tuner/filter/DownloadEvent.java
+++ b/media/java/android/media/tv/tuner/filter/DownloadEvent.java
@@ -16,13 +16,14 @@
 
 package android.media.tv.tuner.filter;
 
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.SystemApi;
 
 /**
  * Filter event sent from {@link Filter} objects with download type.
  *
  * @hide
  */
+@SystemApi
 public class DownloadEvent extends FilterEvent {
     private final int mItemId;
     private final int mMpuSequenceNumber;
diff --git a/media/java/android/media/tv/tuner/filter/DownloadSettings.java b/media/java/android/media/tv/tuner/filter/DownloadSettings.java
index fa7744a..915ad79 100644
--- a/media/java/android/media/tv/tuner/filter/DownloadSettings.java
+++ b/media/java/android/media/tv/tuner/filter/DownloadSettings.java
@@ -18,13 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Filter Settings for a Download.
+ *
  * @hide
  */
+@SystemApi
 public class DownloadSettings extends Settings {
     private final int mDownloadId;
 
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index 3f6154b..06de6e8 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -20,8 +20,8 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.Tuner.FilterCallback;
 import android.media.tv.tuner.TunerConstants.Result;
 
 import java.lang.annotation.Retention;
@@ -34,6 +34,7 @@
  *
  * @hide
  */
+@SystemApi
 public class Filter implements AutoCloseable {
     /** @hide */
     @IntDef(prefix = "TYPE_",
@@ -72,91 +73,107 @@
     public @interface Subtype {}
     /**
      * Filter subtype undefined.
-     * @hide
      */
     public static final int SUBTYPE_UNDEFINED = 0;
     /**
      * Section filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_SECTION = 1;
     /**
      * PES filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_PES = 2;
     /**
      * Audio filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_AUDIO = 3;
     /**
      * Video filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_VIDEO = 4;
     /**
      * Download filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_DOWNLOAD = 5;
     /**
      * Record filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_RECORD = 6;
     /**
      * TS filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_TS = 7;
     /**
      * PCR filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_PCR = 8;
     /**
      * TEMI filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_TEMI = 9;
     /**
      * MMTP filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_MMTP = 10;
     /**
      * NTP filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_NTP = 11;
     /**
      * Payload filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_IP_PAYLOAD = 12;
     /**
      * IP filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_IP = 13;
     /**
      * Payload through filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_PAYLOAD_THROUGH = 14;
     /**
      * TLV filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_TLV = 15;
     /**
      * PTP filter subtype.
-     * @hide
      */
     public static final int SUBTYPE_PTP = 16;
 
 
+
+    /** @hide */
+    @IntDef(flag = true, prefix = "STATUS_", value = {STATUS_DATA_READY, STATUS_LOW_WATER,
+            STATUS_HIGH_WATER, STATUS_OVERFLOW})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Status {}
+
+    /**
+     * The status of a filter that the data in the filter buffer is ready to be read.
+     */
+    public static final int STATUS_DATA_READY = Constants.DemuxFilterStatus.DATA_READY;
+    /**
+     * The status of a filter that the amount of available data in the filter buffer is at low
+     * level.
+     *
+     * The value is set to 25 percent of the buffer size by default. It can be changed when
+     * configuring the filter.
+     */
+    public static final int STATUS_LOW_WATER = Constants.DemuxFilterStatus.LOW_WATER;
+    /**
+     * The status of a filter that the amount of available data in the filter buffer is at high
+     * level.
+     * The value is set to 75 percent of the buffer size by default. It can be changed when
+     * configuring the filter.
+     */
+    public static final int STATUS_HIGH_WATER = Constants.DemuxFilterStatus.HIGH_WATER;
+    /**
+     * The status of a filter that the filter buffer is full and newly filtered data is being
+     * discarded.
+     */
+    public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
+
+
     private long mNativeContext;
     private FilterCallback mCallback;
     private final int mId;
@@ -171,6 +188,7 @@
     private native int nativeRead(byte[] buffer, long offset, long size);
     private native int nativeClose();
 
+    // Called by JNI
     private Filter(int id) {
         mId = id;
     }
@@ -178,6 +196,15 @@
     private void onFilterStatus(int status) {
     }
 
+    /** @hide */
+    public void setCallback(FilterCallback cb) {
+        mCallback = cb;
+    }
+    /** @hide */
+    public FilterCallback getCallback() {
+        return mCallback;
+    }
+
     /**
      * Configures the filter.
      *
@@ -241,7 +268,10 @@
     }
 
     /**
-     * Flushes the filter. Data in filter buffer is cleared.
+     * Flushes the filter.
+     *
+     * <p>The data which is already produced by filter but not consumed yet will
+     * be cleared.
      *
      * @return result status of the operation.
      */
@@ -251,7 +281,7 @@
     }
 
     /**
-     * Copies filtered data from filter buffer to the given byte array.
+     * Copies filtered data from filter output to the given byte array.
      *
      * @param buffer the buffer to store the filtered data.
      * @param offset the index of the first byte in {@code buffer} to write.
diff --git a/media/java/android/media/tv/tuner/filter/FilterCallback.java b/media/java/android/media/tv/tuner/filter/FilterCallback.java
index 888adc5..2ad6bd1 100644
--- a/media/java/android/media/tv/tuner/filter/FilterCallback.java
+++ b/media/java/android/media/tv/tuner/filter/FilterCallback.java
@@ -17,13 +17,14 @@
 package android.media.tv.tuner.filter;
 
 import android.annotation.NonNull;
-import android.media.tv.tuner.TunerConstants.FilterStatus;
+import android.annotation.SystemApi;
 
 /**
  * Callback interface for receiving information from the corresponding filters.
  *
  * @hide
  */
+@SystemApi
 public interface FilterCallback {
     /**
      * Invoked when there are filter events.
@@ -38,5 +39,5 @@
      * @param filter the corresponding filter whose status is changed.
      * @param status the new status of the filter.
      */
-    void onFilterStatusChanged(@NonNull Filter filter, @FilterStatus int status);
+    void onFilterStatusChanged(@NonNull Filter filter, @Filter.Status int status);
 }
diff --git a/media/java/android/media/tv/tuner/filter/FilterConfiguration.java b/media/java/android/media/tv/tuner/filter/FilterConfiguration.java
index c901e2b..c1d2275 100644
--- a/media/java/android/media/tv/tuner/filter/FilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/FilterConfiguration.java
@@ -17,9 +17,9 @@
 package android.media.tv.tuner.filter;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
-import android.hardware.tv.tuner.V1_0.Constants;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -32,37 +32,6 @@
 @SystemApi
 public abstract class FilterConfiguration {
 
-    /**
-     * TODO: moved to Filter. Remove it here.
-     * @hide
-     */
-    @IntDef(prefix = "FILTER_TYPE_", value =
-            {FILTER_TYPE_TS, FILTER_TYPE_MMTP, FILTER_TYPE_IP, FILTER_TYPE_TLV, FILTER_TYPE_ALP})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FilterType {}
-
-    /**
-     * TS filter type.
-     */
-    public static final int FILTER_TYPE_TS = Constants.DemuxFilterMainType.TS;
-    /**
-     * MMTP filter type.
-     */
-    public static final int FILTER_TYPE_MMTP = Constants.DemuxFilterMainType.MMTP;
-    /**
-     * IP filter type.
-     */
-    public static final int FILTER_TYPE_IP = Constants.DemuxFilterMainType.IP;
-    /**
-     * TLV filter type.
-     */
-    public static final int FILTER_TYPE_TLV = Constants.DemuxFilterMainType.TLV;
-    /**
-     * ALP filter type.
-     */
-    public static final int FILTER_TYPE_ALP = Constants.DemuxFilterMainType.ALP;
-
-
     /** @hide */
     @IntDef(prefix = "PACKET_TYPE_", value =
             {PACKET_TYPE_IPV4, PACKET_TYPE_COMPRESSED, PACKET_TYPE_SIGNALING})
@@ -71,17 +40,14 @@
 
     /**
      * IP v4 packet type.
-     * @hide
      */
     public static final int PACKET_TYPE_IPV4 = 0;
     /**
      * Compressed packet type.
-     * @hide
      */
     public static final int PACKET_TYPE_COMPRESSED = 2;
     /**
      * Signaling packet type.
-     * @hide
      */
     public static final int PACKET_TYPE_SIGNALING = 4;
 
@@ -95,12 +61,13 @@
 
     /**
      * Gets filter configuration type.
-     * @hide
      */
-    @FilterType
+    @Filter.Type
     public abstract int getType();
 
-    /** @hide */
+    /**
+     * Gets filter Settings.
+     */
     @Nullable
     public Settings getSettings() {
         return mSettings;
@@ -110,7 +77,6 @@
      * Builder for {@link FilterConfiguration}.
      *
      * @param <T> The subclass to be built.
-     * @hide
      */
     public abstract static class Builder<T extends Builder<T>> {
         /* package */ Settings mSettings;
@@ -121,8 +87,8 @@
         /**
          * Sets filter settings.
          */
-        @Nullable
-        public T setFrequency(Settings settings) {
+        @NonNull
+        public T setSettings(@Nullable Settings settings) {
             mSettings = settings;
             return self();
         }
diff --git a/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java
index 98edf10..bf5aaed 100644
--- a/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java
@@ -19,13 +19,16 @@
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.Size;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Filter configuration for a IP filter.
+ *
  * @hide
  */
+@SystemApi
 public class IpFilterConfiguration extends FilterConfiguration {
     private final byte[] mSrcIpAddress;
     private final byte[] mDstIpAddress;
@@ -33,7 +36,7 @@
     private final int mDstPort;
     private final boolean mPassthrough;
 
-    public IpFilterConfiguration(Settings settings, byte[] srcAddr, byte[] dstAddr, int srcPort,
+    private IpFilterConfiguration(Settings settings, byte[] srcAddr, byte[] dstAddr, int srcPort,
             int dstPort, boolean passthrough) {
         super(settings);
         mSrcIpAddress = srcAddr;
@@ -45,13 +48,14 @@
 
     @Override
     public int getType() {
-        return FilterConfiguration.FILTER_TYPE_IP;
+        return Filter.TYPE_IP;
     }
 
     /**
      * Gets source IP address.
      */
     @Size(min = 4, max = 16)
+    @NonNull
     public byte[] getSrcIpAddress() {
         return mSrcIpAddress;
     }
@@ -59,6 +63,7 @@
      * Gets destination IP address.
      */
     @Size(min = 4, max = 16)
+    @NonNull
     public byte[] getDstIpAddress() {
         return mDstIpAddress;
     }
@@ -113,7 +118,7 @@
          * Sets source IP address.
          */
         @NonNull
-        public Builder setSrcIpAddress(byte[] srcIpAddress) {
+        public Builder setSrcIpAddress(@NonNull byte[] srcIpAddress) {
             mSrcIpAddress = srcIpAddress;
             return this;
         }
@@ -121,7 +126,7 @@
          * Sets destination IP address.
          */
         @NonNull
-        public Builder setDstIpAddress(byte[] dstIpAddress) {
+        public Builder setDstIpAddress(@NonNull byte[] dstIpAddress) {
             mDstIpAddress = dstIpAddress;
             return this;
         }
diff --git a/media/java/android/media/tv/tuner/filter/IpPayloadEvent.java b/media/java/android/media/tv/tuner/filter/IpPayloadEvent.java
index 09489ed..42a124f 100644
--- a/media/java/android/media/tv/tuner/filter/IpPayloadEvent.java
+++ b/media/java/android/media/tv/tuner/filter/IpPayloadEvent.java
@@ -16,13 +16,14 @@
 
 package android.media.tv.tuner.filter;
 
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.SystemApi;
 
 /**
  * Filter event sent from {@link Filter} objects with IP payload type.
  *
  * @hide
  */
+@SystemApi
 public class IpPayloadEvent extends FilterEvent {
     private final int mDataLength;
 
diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java
index 0b5c56b..eb2f4a9 100644
--- a/media/java/android/media/tv/tuner/filter/MediaEvent.java
+++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java
@@ -18,13 +18,14 @@
 
 import android.annotation.BytesLong;
 import android.annotation.Nullable;
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.SystemApi;
 
 /**
  * Filter event sent from {@link Filter} objects with media type.
  *
  * @hide
  */
+@SystemApi
 public class MediaEvent extends FilterEvent{
     private final int mStreamId;
     private final boolean mIsPtsPresent;
@@ -63,11 +64,11 @@
     }
 
     /**
-     * Returns whether PTS is present.
+     * Returns whether PTS (Presentation Time Stamp) is present.
      *
      * @return {@code true} if PTS is present in PES header; {@code false} otherwise.
      */
-    public boolean getIsPtsPresent() {
+    public boolean isPtsPresent() {
         return mIsPtsPresent;
     }
 
@@ -110,7 +111,7 @@
      * @return {@code true} if the data is in secure area, and isn't mappable;
      *         {@code false} otherwise.
      */
-    public boolean getIsSecureMemory() {
+    public boolean isSecureMemory() {
         return mIsSecureMemory;
     }
 
@@ -135,7 +136,7 @@
      *
      * @return {@code true} if the data is in private; {@code false} otherwise.
      */
-    public boolean getIsPrivateData() {
+    public boolean isPrivateData() {
         return mIsPrivateData;
     }
 
diff --git a/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
index 248f23a..0601829 100644
--- a/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
@@ -18,32 +18,35 @@
 
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Filter configuration for a MMTP filter.
+ *
  * @hide
  */
+@SystemApi
 public class MmtpFilterConfiguration extends FilterConfiguration {
     private final int mMmtpPid;
 
-    public MmtpFilterConfiguration(Settings settings, int mmtpPid) {
+    private MmtpFilterConfiguration(Settings settings, int mmtpPid) {
         super(settings);
         mMmtpPid = mmtpPid;
     }
 
     @Override
     public int getType() {
-        return FilterConfiguration.FILTER_TYPE_MMTP;
+        return Filter.TYPE_MMTP;
     }
 
     /**
-     * Gets MMTP PID.
+     * Gets MMTP Packet ID.
      *
      * <p>Packet ID is used to specify packets in MMTP.
      */
-    public int getMmtpPid() {
+    public int getMmtpPacketId() {
         return mMmtpPid;
     }
 
@@ -69,10 +72,10 @@
         }
 
         /**
-         * Sets MMTP PID.
+         * Sets MMTP Packet ID.
          */
         @NonNull
-        public Builder setMmtpPid(int mmtpPid) {
+        public Builder setMmtpPacketId(int mmtpPid) {
             mMmtpPid = mmtpPid;
             return this;
         }
diff --git a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
index 7f37994..093dc6f 100644
--- a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
+++ b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java
@@ -16,21 +16,23 @@
 
 package android.media.tv.tuner.filter;
 
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.BytesLong;
+import android.annotation.SystemApi;
 
 /**
  * Filter event sent from {@link Filter} objects with MMTP type.
  *
  * @hide
  */
+@SystemApi
 public class MmtpRecordEvent extends FilterEvent {
     private final int mScHevcIndexMask;
-    private final long mByteNumber;
+    private final long mDataLength;
 
     // This constructor is used by JNI code only
-    private MmtpRecordEvent(int scHevcIndexMask, long byteNumber) {
+    private MmtpRecordEvent(int scHevcIndexMask, long dataLength) {
         mScHevcIndexMask = scHevcIndexMask;
-        mByteNumber = byteNumber;
+        mDataLength = dataLength;
     }
 
     /**
@@ -41,9 +43,10 @@
     }
 
     /**
-     * Gets the byte number from beginning of the filter's output.
+     * Gets data size in bytes of filtered data.
      */
-    public long getByteNumber() {
-        return mByteNumber;
+    @BytesLong
+    public long getDataLength() {
+        return mDataLength;
     }
 }
diff --git a/media/java/android/media/tv/tuner/filter/PesEvent.java b/media/java/android/media/tv/tuner/filter/PesEvent.java
index 60251bf..695e596 100644
--- a/media/java/android/media/tv/tuner/filter/PesEvent.java
+++ b/media/java/android/media/tv/tuner/filter/PesEvent.java
@@ -16,13 +16,14 @@
 
 package android.media.tv.tuner.filter;
 
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.SystemApi;
 
 /**
  * Filter event sent from {@link Filter} objects with PES type.
  *
  * @hide
  */
+@SystemApi
 public class PesEvent extends FilterEvent {
     private final int mStreamId;
     private final int mDataLength;
diff --git a/media/java/android/media/tv/tuner/filter/RecordSettings.java b/media/java/android/media/tv/tuner/filter/RecordSettings.java
index 4e9d67f..209ed67 100644
--- a/media/java/android/media/tv/tuner/filter/RecordSettings.java
+++ b/media/java/android/media/tv/tuner/filter/RecordSettings.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
 import android.media.tv.tuner.TunerConstants;
@@ -30,8 +31,10 @@
 
 /**
  * The Settings for the record in DVR.
+ *
  * @hide
  */
+@SystemApi
 public class RecordSettings extends Settings {
     /**
      * Indexes can be tagged through TS (Transport Stream) header.
@@ -51,74 +54,61 @@
 
     /**
      * TS index FIRST_PACKET.
-     * @hide
      */
     public static final int TS_INDEX_FIRST_PACKET = Constants.DemuxTsIndex.FIRST_PACKET;
     /**
      * TS index PAYLOAD_UNIT_START_INDICATOR.
-     * @hide
      */
     public static final int TS_INDEX_PAYLOAD_UNIT_START_INDICATOR =
             Constants.DemuxTsIndex.PAYLOAD_UNIT_START_INDICATOR;
     /**
      * TS index CHANGE_TO_NOT_SCRAMBLED.
-     * @hide
      */
     public static final int TS_INDEX_CHANGE_TO_NOT_SCRAMBLED =
             Constants.DemuxTsIndex.CHANGE_TO_NOT_SCRAMBLED;
     /**
      * TS index CHANGE_TO_EVEN_SCRAMBLED.
-     * @hide
      */
     public static final int TS_INDEX_CHANGE_TO_EVEN_SCRAMBLED =
             Constants.DemuxTsIndex.CHANGE_TO_EVEN_SCRAMBLED;
     /**
      * TS index CHANGE_TO_ODD_SCRAMBLED.
-     * @hide
      */
     public static final int TS_INDEX_CHANGE_TO_ODD_SCRAMBLED =
             Constants.DemuxTsIndex.CHANGE_TO_ODD_SCRAMBLED;
     /**
      * TS index DISCONTINUITY_INDICATOR.
-     * @hide
      */
     public static final int TS_INDEX_DISCONTINUITY_INDICATOR =
             Constants.DemuxTsIndex.DISCONTINUITY_INDICATOR;
     /**
      * TS index RANDOM_ACCESS_INDICATOR.
-     * @hide
      */
     public static final int TS_INDEX_RANDOM_ACCESS_INDICATOR =
             Constants.DemuxTsIndex.RANDOM_ACCESS_INDICATOR;
     /**
      * TS index PRIORITY_INDICATOR.
-     * @hide
      */
     public static final int TS_INDEX_PRIORITY_INDICATOR = Constants.DemuxTsIndex.PRIORITY_INDICATOR;
     /**
      * TS index PCR_FLAG.
-     * @hide
      */
     public static final int TS_INDEX_PCR_FLAG = Constants.DemuxTsIndex.PCR_FLAG;
     /**
      * TS index OPCR_FLAG.
-     * @hide
      */
     public static final int TS_INDEX_OPCR_FLAG = Constants.DemuxTsIndex.OPCR_FLAG;
     /**
      * TS index SPLICING_POINT_FLAG.
-     * @hide
      */
     public static final int TS_INDEX_SPLICING_POINT_FLAG =
             Constants.DemuxTsIndex.SPLICING_POINT_FLAG;
     /**
      * TS index PRIVATE_DATA.
-     * @hide
      */
     public static final int TS_INDEX_PRIVATE_DATA = Constants.DemuxTsIndex.PRIVATE_DATA;
     /**
      * TS index ADAPTATION_EXTENSION_FLAG.
-     * @hide
      */
     public static final int TS_INDEX_ADAPTATION_EXTENSION_FLAG =
             Constants.DemuxTsIndex.ADAPTATION_EXTENSION_FLAG;
diff --git a/media/java/android/media/tv/tuner/filter/SectionEvent.java b/media/java/android/media/tv/tuner/filter/SectionEvent.java
index e211dda..ff12492 100644
--- a/media/java/android/media/tv/tuner/filter/SectionEvent.java
+++ b/media/java/android/media/tv/tuner/filter/SectionEvent.java
@@ -17,7 +17,6 @@
 package android.media.tv.tuner.filter;
 
 import android.annotation.SystemApi;
-import android.media.tv.tuner.Tuner.Filter;
 
 /**
  * Filter event sent from {@link Filter} objects with section type.
diff --git a/media/java/android/media/tv/tuner/filter/SectionSettings.java b/media/java/android/media/tv/tuner/filter/SectionSettings.java
index b8d0fad..70788a7 100644
--- a/media/java/android/media/tv/tuner/filter/SectionSettings.java
+++ b/media/java/android/media/tv/tuner/filter/SectionSettings.java
@@ -16,12 +16,15 @@
 
 package android.media.tv.tuner.filter;
 
+import android.annotation.SystemApi;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Filter Settings for Section data according to ISO/IEC 13818-1.
+ *
  * @hide
  */
+@SystemApi
 public class SectionSettings extends Settings {
 
     SectionSettings(int mainType) {
diff --git a/media/java/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java b/media/java/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java
index a2d42d8..eeeabdf 100644
--- a/media/java/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java
+++ b/media/java/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java
@@ -18,13 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Bits Settings for Section Filters.
+ *
  * @hide
  */
+@SystemApi
 public class SectionSettingsWithSectionBits extends SectionSettings {
     private final byte[] mFilter;
     private final byte[] mMask;
@@ -41,6 +44,7 @@
     /**
      * Gets the bytes configured for Section Filter
      */
+    @NonNull
     public byte[] getFilterBytes() {
         return mFilter;
     }
@@ -49,6 +53,7 @@
      *
      * <p>The bits in the bytes are used for filtering.
      */
+    @NonNull
     public byte[] getMask() {
         return mMask;
     }
@@ -60,6 +65,7 @@
      * <p>Do negative match at the bit position of the configured bytes when the bit at same
      * position of the mode is 1.
      */
+    @NonNull
     public byte[] getMode() {
         return mMode;
     }
@@ -93,7 +99,7 @@
          * Sets filter bytes.
          */
         @NonNull
-        public Builder setFilter(byte[] filter) {
+        public Builder setFilter(@NonNull byte[] filter) {
             mFilter = filter;
             return this;
         }
@@ -101,7 +107,7 @@
          * Sets bit mask.
          */
         @NonNull
-        public Builder setMask(byte[] mask) {
+        public Builder setMask(@NonNull byte[] mask) {
             mMask = mask;
             return this;
         }
@@ -109,7 +115,7 @@
          * Sets mode.
          */
         @NonNull
-        public Builder setMode(byte[] mode) {
+        public Builder setMode(@NonNull byte[] mode) {
             mMode = mode;
             return this;
         }
diff --git a/media/java/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java b/media/java/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java
index 0c9cd2b..c5ff45c 100644
--- a/media/java/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java
+++ b/media/java/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java
@@ -18,13 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Table information for Section Filter.
+ *
  * @hide
  */
+@SystemApi
 public class SectionSettingsWithTableInfo extends SectionSettings {
     private final int mTableId;
     private final int mVersion;
diff --git a/media/java/android/media/tv/tuner/filter/Settings.java b/media/java/android/media/tv/tuner/filter/Settings.java
index d697280..fee7f66 100644
--- a/media/java/android/media/tv/tuner/filter/Settings.java
+++ b/media/java/android/media/tv/tuner/filter/Settings.java
@@ -33,8 +33,6 @@
 
     /**
      * Gets filter settings type.
-     *
-     * @hide
      */
     public int getType() {
         return mType;
@@ -45,7 +43,6 @@
      * Builder for {@link Settings}.
      *
      * @param <T> The subclass to be built.
-     * @hide
      */
     public abstract static class Builder<T extends Builder<T>> {
         /* package */ final int mMainType;
diff --git a/media/java/android/media/tv/tuner/filter/TemiEvent.java b/media/java/android/media/tv/tuner/filter/TemiEvent.java
index 031fa5c..9bee928 100644
--- a/media/java/android/media/tv/tuner/filter/TemiEvent.java
+++ b/media/java/android/media/tv/tuner/filter/TemiEvent.java
@@ -17,13 +17,14 @@
 package android.media.tv.tuner.filter;
 
 import android.annotation.NonNull;
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.SystemApi;
 
 /**
  * Filter event sent from {@link Filter} objects for Timed External Media Information (TEMI) data.
  *
  * @hide
  */
+@SystemApi
 public class TemiEvent extends FilterEvent {
     private final long mPts;
     private final byte mDescrTag;
@@ -45,14 +46,14 @@
     }
 
     /**
-     * Gets TEMI descriptor tag.
+     * Gets TEMI (Timed External Media Information) descriptor tag.
      */
     public byte getDescriptorTag() {
         return mDescrTag;
     }
 
     /**
-     * Gets TEMI descriptor.
+     * Gets TEMI (Timed External Media Information) descriptor.
      */
     @NonNull
     public byte[] getDescriptorData() {
diff --git a/media/java/android/media/tv/tuner/filter/TimeFilter.java b/media/java/android/media/tv/tuner/filter/TimeFilter.java
index c975004..a926d59 100644
--- a/media/java/android/media/tv/tuner/filter/TimeFilter.java
+++ b/media/java/android/media/tv/tuner/filter/TimeFilter.java
@@ -16,7 +16,7 @@
 
 package android.media.tv.tuner.filter;
 
-import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.media.tv.tuner.TunerConstants.Result;
 
 /**
@@ -30,7 +30,21 @@
  *
  * @hide
  */
+@SystemApi
 public class TimeFilter implements AutoCloseable {
+
+    /**
+     * Timestamp is unavailable.
+     *
+     * <p>Returned by {@link #getSourceTime()} or {@link #getTimeStamp()} when the requested
+     * timestamp is not available.
+     *
+     * @see #getSourceTime()
+     * @see #getTimeStamp()
+     */
+    public static final long TIMESTAMP_UNAVAILABLE = -1L;
+
+
     private native int nativeSetTimestamp(long timestamp);
     private native int nativeClearTimestamp();
     private native Long nativeGetTimestamp();
@@ -39,6 +53,10 @@
 
     private boolean mEnable = false;
 
+    // Called by JNI code
+    private TimeFilter() {
+    }
+
     /**
      * Set timestamp for time based filter.
      *
@@ -86,13 +104,12 @@
      *
      * @return current timestamp in the time filter. It's based on the 90KHz counter, and it's
      * the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019. The
-     * timestamps may or may not be related to PTS or DTS. {@code null} if the timestamp is
-     * never set.
+     * timestamps may or may not be related to PTS or DTS. Returns {@link #TIMESTAMP_UNAVAILABLE}
+     * if the timestamp is never set.
      */
-    @Nullable
-    public Long getTimeStamp() {
+    public long getTimeStamp() {
         if (!mEnable) {
-            return null;
+            return TIMESTAMP_UNAVAILABLE;
         }
         return nativeGetTimestamp();
     }
@@ -104,12 +121,12 @@
      *
      * @return first timestamp of incoming data stream. It's based on the 90KHz counter, and
      * it's the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019.
-     * The timestamps may or may not be related to PTS or DTS.
+     * The timestamps may or may not be related to PTS or DTS. Returns
+     * {@link #TIMESTAMP_UNAVAILABLE} if the timestamp is not available.
      */
-    @Nullable
-    public Long getSourceTime() {
+    public long getSourceTime() {
         if (!mEnable) {
-            return null;
+            return TIMESTAMP_UNAVAILABLE;
         }
         return nativeGetSourceTime();
     }
diff --git a/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java
index eb97fc0..b6878e6 100644
--- a/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java
@@ -18,19 +18,22 @@
 
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.tv.tuner.TunerUtils;
 
 /**
  * Filter configuration for a TLV filter.
+ *
  * @hide
  */
+@SystemApi
 public class TlvFilterConfiguration extends FilterConfiguration {
     private final int mPacketType;
     private final boolean mIsCompressedIpPacket;
     private final boolean mPassthrough;
 
-    public TlvFilterConfiguration(Settings settings, int packetType, boolean isCompressed,
+    private TlvFilterConfiguration(Settings settings, int packetType, boolean isCompressed,
             boolean passthrough) {
         super(settings);
         mPacketType = packetType;
@@ -40,7 +43,7 @@
 
     @Override
     public int getType() {
-        return FilterConfiguration.FILTER_TYPE_TLV;
+        return Filter.TYPE_TLV;
     }
 
     /**
diff --git a/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java
index 5c38cfa..f186de6 100644
--- a/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java
@@ -39,7 +39,7 @@
 
     @Override
     public int getType() {
-        return FilterConfiguration.FILTER_TYPE_TS;
+        return Filter.TYPE_TS;
     }
 
     /**
diff --git a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
index 1b8485e..7a14bb8 100644
--- a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
+++ b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java
@@ -16,7 +16,8 @@
 
 package android.media.tv.tuner.filter;
 
-import android.media.tv.tuner.Tuner.Filter;
+import android.annotation.BytesLong;
+import android.annotation.SystemApi;
 
 
 /**
@@ -24,37 +25,38 @@
  *
  * @hide
  */
+@SystemApi
 public class TsRecordEvent extends FilterEvent {
 
     private final int mPid;
     private final int mTsIndexMask;
     private final int mScIndexMask;
-    private final long mByteNumber;
+    private final long mDataLength;
 
     // This constructor is used by JNI code only
-    private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long byteNumber) {
+    private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long dataLength) {
         mPid = pid;
         mTsIndexMask = tsIndexMask;
         mScIndexMask = scIndexMask;
-        mByteNumber = byteNumber;
+        mDataLength = dataLength;
     }
 
     /**
      * Gets packet ID.
      */
-    public int getTpid() {
+    public int getPacketId() {
         return mPid;
     }
 
     /**
-     * Gets TS index mask.
+     * Gets TS (transport stream) index mask.
      */
     @RecordSettings.TsIndexMask
     public int getTsIndexMask() {
         return mTsIndexMask;
     }
     /**
-     * Gets SC index mask.
+     * Gets SC (Start Code) index mask.
      *
      * <p>The index type is SC or SC-HEVC, and is set when configuring the filter.
      */
@@ -64,9 +66,10 @@
     }
 
     /**
-     * Gets the byte number from beginning of the filter's output.
+     * Gets data size in bytes of filtered data.
      */
-    public long getByteNumber() {
-        return mByteNumber;
+    @BytesLong
+    public long getDataLength() {
+        return mDataLength;
     }
 }
diff --git a/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
index a30ddc7..61880ab 100644
--- a/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
@@ -18,7 +18,11 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.TunerUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -28,11 +32,14 @@
  *
  * @hide
  */
+@SystemApi
 public class AnalogFrontendSettings extends FrontendSettings {
     /** @hide */
     @IntDef(flag = true,
             prefix = "SIGNAL_TYPE_",
-            value = {SIGNAL_TYPE_UNDEFINED, SIGNAL_TYPE_PAL, SIGNAL_TYPE_SECAM, SIGNAL_TYPE_NTSC})
+            value = {SIGNAL_TYPE_UNDEFINED, SIGNAL_TYPE_AUTO, SIGNAL_TYPE_PAL, SIGNAL_TYPE_PAL_M,
+              SIGNAL_TYPE_PAL_N, SIGNAL_TYPE_PAL_60, SIGNAL_TYPE_NTSC, SIGNAL_TYPE_NTSC_443,
+              SIGNAL_TYPE_SECAM})
     @Retention(RetentionPolicy.SOURCE)
     public @interface SignalType {}
 
@@ -41,25 +48,44 @@
      */
     public static final int SIGNAL_TYPE_UNDEFINED = Constants.FrontendAnalogType.UNDEFINED;
     /**
+     * AUTO analog signal type.
+     */
+    public static final int SIGNAL_TYPE_AUTO = Constants.FrontendAnalogType.AUTO;
+    /**
      * PAL analog signal type.
      */
     public static final int SIGNAL_TYPE_PAL = Constants.FrontendAnalogType.PAL;
     /**
-     * SECM analog signal type.
+     * PAL M analog signal type.
      */
-    public static final int SIGNAL_TYPE_SECAM = Constants.FrontendAnalogType.SECAM;
+    public static final int SIGNAL_TYPE_PAL_M = Constants.FrontendAnalogType.PAL_M;
+    /**
+     * PAL N analog signal type.
+     */
+    public static final int SIGNAL_TYPE_PAL_N = Constants.FrontendAnalogType.PAL_N;
+    /**
+     * PAL 60 analog signal type.
+     */
+    public static final int SIGNAL_TYPE_PAL_60 = Constants.FrontendAnalogType.PAL_60;
     /**
      * NTSC analog signal type.
      */
     public static final int SIGNAL_TYPE_NTSC = Constants.FrontendAnalogType.NTSC;
-
+    /**
+     * NTSC 443 analog signal type.
+     */
+    public static final int SIGNAL_TYPE_NTSC_443 = Constants.FrontendAnalogType.NTSC_443;
+    /**
+     * SECM analog signal type.
+     */
+    public static final int SIGNAL_TYPE_SECAM = Constants.FrontendAnalogType.SECAM;
 
     /** @hide */
     @IntDef(flag = true,
             prefix = "SIF_",
-            value = {SIF_UNDEFINED, SIF_BG, SIF_BG_A2, SIF_BG_NICAM, SIF_I, SIF_DK,
-            SIF_DK1, SIF_DK2, SIF_DK3, SIF_DK_NICAM, SIF_L, SIF_M, SIF_M_BTSC, SIF_M_A2,
-            SIF_M_EIA_J, SIF_I_NICAM, SIF_L_NICAM, SIF_L_PRIME})
+            value = {SIF_UNDEFINED, SIF_AUTO, SIF_BG, SIF_BG_A2, SIF_BG_NICAM, SIF_I, SIF_DK,
+            SIF_DK1_A2, SIF_DK2_A2, SIF_DK3_A2, SIF_DK_NICAM, SIF_L, SIF_M, SIF_M_BTSC, SIF_M_A2,
+            SIF_M_EIAJ, SIF_I_NICAM, SIF_L_NICAM, SIF_L_PRIME})
     @Retention(RetentionPolicy.SOURCE)
     public @interface SifStandard {}
 
@@ -68,6 +94,10 @@
      */
     public static final int SIF_UNDEFINED = Constants.FrontendAnalogSifStandard.UNDEFINED;
     /**
+     * Audo Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_AUTO = Constants.FrontendAnalogSifStandard.AUTO;
+     /**
      * BG Analog Standard Interchange Format (SIF).
      */
     public static final int SIF_BG = Constants.FrontendAnalogSifStandard.BG;
@@ -88,17 +118,17 @@
      */
     public static final int SIF_DK = Constants.FrontendAnalogSifStandard.DK;
     /**
-     * DK1 Analog Standard Interchange Format (SIF).
+     * DK1 A2 Analog Standard Interchange Format (SIF).
      */
-    public static final int SIF_DK1 = Constants.FrontendAnalogSifStandard.DK1;
+    public static final int SIF_DK1_A2 = Constants.FrontendAnalogSifStandard.DK1_A2;
     /**
-     * DK2 Analog Standard Interchange Format (SIF).
+     * DK2 A2 Analog Standard Interchange Format (SIF).
      */
-    public static final int SIF_DK2 = Constants.FrontendAnalogSifStandard.DK2;
+    public static final int SIF_DK2_A2 = Constants.FrontendAnalogSifStandard.DK2_A2;
     /**
-     * DK3 Analog Standard Interchange Format (SIF).
+     * DK3 A2 Analog Standard Interchange Format (SIF).
      */
-    public static final int SIF_DK3 = Constants.FrontendAnalogSifStandard.DK3;
+    public static final int SIF_DK3_A2 = Constants.FrontendAnalogSifStandard.DK3_A2;
     /**
      * DK-NICAM Analog Standard Interchange Format (SIF).
      */
@@ -120,9 +150,9 @@
      */
     public static final int SIF_M_A2 = Constants.FrontendAnalogSifStandard.M_A2;
     /**
-     * M-EIA-J Analog Standard Interchange Format (SIF).
+     * M-EIAJ Analog Standard Interchange Format (SIF).
      */
-    public static final int SIF_M_EIA_J = Constants.FrontendAnalogSifStandard.M_EIA_J;
+    public static final int SIF_M_EIAJ = Constants.FrontendAnalogSifStandard.M_EIAJ;
     /**
      * I-NICAM Analog Standard Interchange Format (SIF).
      */
@@ -137,7 +167,7 @@
     public static final int SIF_L_PRIME = Constants.FrontendAnalogSifStandard.L_PRIME;
 
 
-    private final int mAnalogType;
+    private final int mSignalType;
     private final int mSifStandard;
 
     @Override
@@ -150,8 +180,8 @@
      * Gets analog signal type.
      */
     @SignalType
-    public int getAnalogType() {
-        return mAnalogType;
+    public int getSignalType() {
+        return mSignalType;
     }
 
     /**
@@ -164,43 +194,37 @@
 
     /**
      * Creates a builder for {@link AnalogFrontendSettings}.
+     *
+     * @param the context of the caller.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @NonNull
-    public static Builder newBuilder() {
+    public static Builder builder(@NonNull Context context) {
+        TunerUtils.checkTunerPermission(context);
         return new Builder();
     }
 
-    private AnalogFrontendSettings(int frequency, int analogType, int sifStandard) {
+    private AnalogFrontendSettings(int frequency, int signalType, int sifStandard) {
         super(frequency);
-        mAnalogType = analogType;
+        mSignalType = signalType;
         mSifStandard = sifStandard;
     }
 
     /**
      * Builder for {@link AnalogFrontendSettings}.
      */
-    public static class Builder {
-        private int mFrequency;
-        private int mAnalogType;
+    public static class Builder extends FrontendSettings.Builder<Builder> {
+        private int mSignalType;
         private int mSifStandard;
 
         private Builder() {}
 
         /**
-         * Sets frequency in Hz.
+         * Sets analog signal type.
          */
         @NonNull
-        public Builder setFrequency(int frequency) {
-            mFrequency = frequency;
-            return this;
-        }
-
-        /**
-         * Sets analog type.
-         */
-        @NonNull
-        public Builder setAnalogType(@SignalType int analogType) {
-            mAnalogType = analogType;
+        public Builder setASignalType(@SignalType int signalType) {
+            mSignalType = signalType;
             return this;
         }
 
@@ -218,7 +242,12 @@
          */
         @NonNull
         public AnalogFrontendSettings build() {
-            return new AnalogFrontendSettings(mFrequency, mAnalogType, mSifStandard);
+            return new AnalogFrontendSettings(mFrequency, mSignalType, mSifStandard);
+        }
+
+        @Override
+        Builder self() {
+            return this;
         }
     }
 }
diff --git a/media/java/android/media/tv/tuner/frontend/Atsc3PlpInfo.java b/media/java/android/media/tv/tuner/frontend/Atsc3PlpInfo.java
new file mode 100644
index 0000000..9900fec
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/Atsc3PlpInfo.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/** PLP information for ATSC3.
+ * @hide
+ */
+@SystemApi
+public class Atsc3PlpInfo {
+    private final int mPlpId;
+    private final boolean mLlsFlag;
+
+    private Atsc3PlpInfo(int plpId, boolean llsFlag) {
+        mPlpId = plpId;
+        mLlsFlag = llsFlag;
+    }
+
+    /** Gets PLP IDs. */
+    public int getPlpId() {
+        return mPlpId;
+    }
+
+    /** Gets LLS flag. */
+    public boolean getLlsFlag() {
+        return mLlsFlag;
+    }
+}
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendSettings.java b/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
index 617d608..b80b7cd 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.hardware.tv.tuner.V1_0.Constants;
 
 import java.lang.annotation.Retention;
@@ -29,6 +30,7 @@
  *
  * @hide
  */
+@SystemApi
 public abstract class FrontendSettings {
     /** @hide */
     @IntDef({TYPE_UNDEFINED, TYPE_ANALOG, TYPE_ATSC, TYPE_ATSC3, TYPE_DVBC, TYPE_DVBS, TYPE_DVBT,
diff --git a/media/java/android/media/tv/tuner/frontend/OnTuneEventListener.java b/media/java/android/media/tv/tuner/frontend/OnTuneEventListener.java
new file mode 100644
index 0000000..5cf0d31
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/OnTuneEventListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Listens for tune events.
+ *
+ * @hide
+ */
+@SystemApi
+public interface OnTuneEventListener {
+
+    /** @hide */
+    @IntDef(prefix = "SIGNAL_", value = {SIGNAL_LOCKED, SIGNAL_NO_SIGNAL, SIGNAL_LOST_LOCK})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface TuneEvent {}
+
+    /** The frontend has locked to the signal specified by the tune method. */
+    int SIGNAL_LOCKED = Constants.FrontendEventType.LOCKED;
+    /** The frontend is unable to lock to the signal specified by the tune method. */
+    int SIGNAL_NO_SIGNAL = Constants.FrontendEventType.NO_SIGNAL;
+    /** The frontend has lost the lock to the signal specified by the tune method. */
+    int SIGNAL_LOST_LOCK = Constants.FrontendEventType.LOST_LOCK;
+
+    /** Tune Event from the frontend */
+    void onTuneEvent(@TuneEvent int tuneEvent);
+}
diff --git a/media/java/android/media/tv/tuner/frontend/ScanCallback.java b/media/java/android/media/tv/tuner/frontend/ScanCallback.java
index a825d6d..f90144b 100644
--- a/media/java/android/media/tv/tuner/frontend/ScanCallback.java
+++ b/media/java/android/media/tv/tuner/frontend/ScanCallback.java
@@ -16,41 +16,18 @@
 
 package android.media.tv.tuner.frontend;
 
-import android.annotation.IntDef;
-import android.hardware.tv.tuner.V1_0.Constants;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 
 /**
  * Scan callback.
  *
  * @hide
  */
+@SystemApi
 public interface ScanCallback {
 
-    /** @hide */
-    @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface ScanType {}
-    /**
-     * Scan type undefined.
-     */
-    int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
-    /**
-     * Scan type auto.
-     *
-     * <p> Tuner will send {@link #onLocked}
-     */
-    int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
-    /**
-     * Blind scan.
-     *
-     * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
-     * implementation specific range.
-     */
-    int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
-
     /** Scan locked the signal. */
     void onLocked();
 
@@ -58,22 +35,22 @@
     void onScanStopped();
 
     /** scan progress percent (0..100) */
-    void onProgress(int percent);
+    void onProgress(@IntRange(from = 0, to = 100) int percent);
 
     /** Signal frequencies in Hertz */
-    void onFrequenciesReport(int[] frequency);
+    void onFrequenciesReport(@NonNull int[] frequency);
 
     /** Symbols per second */
-    void onSymbolRates(int[] rate);
+    void onSymbolRates(@NonNull int[] rate);
 
     /** Locked Plp Ids for DVBT2 frontend. */
-    void onPlpIds(int[] plpIds);
+    void onPlpIds(@NonNull int[] plpIds);
 
     /** Locked group Ids for DVBT2 frontend. */
-    void onGroupIds(int[] groupIds);
+    void onGroupIds(@NonNull int[] groupIds);
 
     /** Stream Ids. */
-    void onInputStreamIds(int[] inputStreamIds);
+    void onInputStreamIds(@NonNull int[] inputStreamIds);
 
     /** Locked signal standard for DVBS. */
     void onDvbsStandard(@DvbsFrontendSettings.Standard int dvbsStandandard);
@@ -85,7 +62,7 @@
     void onAnalogSifStandard(@AnalogFrontendSettings.SifStandard int sif);
 
     /** PLP status in a tuned frequency band for ATSC3 frontend. */
-    void onAtsc3PlpInfos(Atsc3PlpInfo[] atsc3PlpInfos);
+    void onAtsc3PlpInfos(@NonNull Atsc3PlpInfo[] atsc3PlpInfos);
 
     /** Frontend hierarchy. */
     void onHierarchy(@DvbtFrontendSettings.Hierarchy int hierarchy);
@@ -93,24 +70,4 @@
     /** Frontend hierarchy. */
     void onSignalType(@AnalogFrontendSettings.SignalType int signalType);
 
-    /** PLP information for ATSC3. */
-    class Atsc3PlpInfo {
-        private final int mPlpId;
-        private final boolean mLlsFlag;
-
-        private Atsc3PlpInfo(int plpId, boolean llsFlag) {
-            mPlpId = plpId;
-            mLlsFlag = llsFlag;
-        }
-
-        /** Gets PLP IDs. */
-        public int getPlpId() {
-            return mPlpId;
-        }
-
-        /** Gets LLS flag. */
-        public boolean getLlsFlag() {
-            return mLlsFlag;
-        }
-    }
 }
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
index 32d03db..daaa868 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
@@ -43,12 +43,11 @@
 import android.content.Context;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2;
-import android.media.MediaRouter2.OnCreateSessionListener;
+import android.media.MediaRouter2.OnGetControllerHintsListener;
 import android.media.MediaRouter2.RouteCallback;
 import android.media.MediaRouter2.RoutingController;
-import android.media.MediaRouter2.SessionCallback;
+import android.media.MediaRouter2.RoutingControllerCallback;
 import android.media.RouteDiscoveryPreference;
-import android.media.RoutingSessionInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -156,33 +155,34 @@
     }
 
     @Test
-    public void testRegisterSessionCallbackWithInvalidArguments() {
+    public void testRegisterControllerCallbackWithInvalidArguments() {
         Executor executor = mExecutor;
-        SessionCallback callback = new SessionCallback();
+        RoutingControllerCallback callback = new RoutingControllerCallback();
 
         // Tests null executor
         assertThrows(NullPointerException.class,
-                () -> mRouter2.registerSessionCallback(null, callback));
+                () -> mRouter2.registerControllerCallback(null, callback));
 
         // Tests null callback
         assertThrows(NullPointerException.class,
-                () -> mRouter2.registerSessionCallback(executor, null));
+                () -> mRouter2.registerControllerCallback(executor, null));
     }
 
     @Test
-    public void testUnregisterSessionCallbackWithNullCallback() {
+    public void testUnregisterControllerCallbackWithNullCallback() {
         // Tests null callback
         assertThrows(NullPointerException.class,
-                () -> mRouter2.unregisterSessionCallback(null));
+                () -> mRouter2.unregisterControllerCallback(null));
     }
 
     @Test
-    public void testRequestCreateSessionWithNullRoute() {
-        assertThrows(NullPointerException.class, () -> mRouter2.requestCreateSession(null));
+    public void testRequestCreateControllerWithNullRoute() {
+        assertThrows(NullPointerException.class,
+                () -> mRouter2.requestCreateController(null));
     }
 
     @Test
-    public void testRequestCreateSessionSuccess() throws Exception {
+    public void testRequestCreateControllerSuccess() throws Exception {
         final List<String> sampleRouteFeature = new ArrayList<>();
         sampleRouteFeature.add(FEATURE_SAMPLE);
 
@@ -195,9 +195,9 @@
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with this route
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 assertNotNull(controller);
                 assertTrue(createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1));
                 controllers.add(controller);
@@ -205,7 +205,7 @@
             }
 
             @Override
-            public void onSessionCreationFailed(MediaRoute2Info requestedRoute) {
+            public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
                 failureLatch.countDown();
             }
         };
@@ -215,8 +215,8 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(route);
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(route);
             assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             // onSessionCreationFailed should not be called.
@@ -224,12 +224,12 @@
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
     @Test
-    public void testRequestCreateSessionFailure() throws Exception {
+    public void testRequestCreateControllerFailure() throws Exception {
         final List<String> sampleRouteType = new ArrayList<>();
         sampleRouteType.add(FEATURE_SAMPLE);
 
@@ -242,15 +242,15 @@
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with this route
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 controllers.add(controller);
                 successLatch.countDown();
             }
 
             @Override
-            public void onSessionCreationFailed(MediaRoute2Info requestedRoute) {
+            public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
                 assertEquals(route, requestedRoute);
                 failureLatch.countDown();
             }
@@ -261,8 +261,8 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(route);
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(route);
             assertTrue(failureLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             // onSessionCreated should not be called.
@@ -270,12 +270,12 @@
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
     @Test
-    public void testRequestCreateSessionMultipleSessions() throws Exception {
+    public void testRequestCreateControllerMultipleSessions() throws Exception {
         final List<String> sampleRouteType = new ArrayList<>();
         sampleRouteType.add(FEATURE_SAMPLE);
 
@@ -284,15 +284,15 @@
         final List<RoutingController> createdControllers = new ArrayList<>();
 
         // Create session with this route
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 createdControllers.add(controller);
                 successLatch.countDown();
             }
 
             @Override
-            public void onSessionCreationFailed(MediaRoute2Info requestedRoute) {
+            public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
                 failureLatch.countDown();
             }
         };
@@ -308,9 +308,9 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(route1);
-            mRouter2.requestCreateSession(route2);
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(route1);
+            mRouter2.requestCreateController(route2);
             assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             // onSessionCreationFailed should not be called.
@@ -321,19 +321,19 @@
             RoutingController controller1 = createdControllers.get(0);
             RoutingController controller2 = createdControllers.get(1);
 
-            assertNotEquals(controller1.getSessionId(), controller2.getSessionId());
+            assertNotEquals(controller1.getId(), controller2.getId());
             assertTrue(createRouteMap(controller1.getSelectedRoutes()).containsKey(ROUTE_ID1));
             assertTrue(createRouteMap(controller2.getSelectedRoutes()).containsKey(ROUTE_ID2));
 
         } finally {
             releaseControllers(createdControllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
     @Test
-    public void testSetOnCreateSessionListener() throws Exception {
+    public void testSetOnGetControllerHintsListener() throws Exception {
         final List<String> sampleRouteFeature = new ArrayList<>();
         sampleRouteFeature.add(FEATURE_SAMPLE);
 
@@ -343,9 +343,9 @@
 
         final Bundle createSessionHints = new Bundle();
         createSessionHints.putString(TEST_KEY, TEST_VALUE);
-        final OnCreateSessionListener listener = new OnCreateSessionListener() {
+        final OnGetControllerHintsListener listener = new OnGetControllerHintsListener() {
             @Override
-            public Bundle onCreateSession(MediaRoute2Info route) {
+            public Bundle onGetControllerHints(MediaRoute2Info route) {
                 return createSessionHints;
             }
         };
@@ -355,9 +355,9 @@
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with this route
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 assertNotNull(controller);
                 assertTrue(createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1));
 
@@ -373,7 +373,7 @@
             }
 
             @Override
-            public void onSessionCreationFailed(MediaRoute2Info requestedRoute) {
+            public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
                 failureLatch.countDown();
             }
         };
@@ -383,12 +383,12 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
 
             // The SampleMediaRoute2ProviderService supposed to set control hints
             // with the given creationSessionHints.
-            mRouter2.setOnCreateSessionListener(listener);
-            mRouter2.requestCreateSession(route);
+            mRouter2.setOnGetControllerHintsListener(listener);
+            mRouter2.requestCreateController(route);
             assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             // onSessionCreationFailed should not be called.
@@ -396,12 +396,12 @@
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
     @Test
-    public void testSessionCallbackIsNotCalledAfterUnregistered() throws Exception {
+    public void testRoutingControllerCallbackIsNotCalledAfterUnregistered() throws Exception {
         final List<String> sampleRouteType = new ArrayList<>();
         sampleRouteType.add(FEATURE_SAMPLE);
 
@@ -414,15 +414,15 @@
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with this route
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 controllers.add(controller);
                 successLatch.countDown();
             }
 
             @Override
-            public void onSessionCreationFailed(MediaRoute2Info requestedRoute) {
+            public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
                 failureLatch.countDown();
             }
         };
@@ -432,11 +432,11 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(route);
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(route);
 
             // Unregisters session callback
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
 
             // No session callback methods should be called.
             assertFalse(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
@@ -444,7 +444,7 @@
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
@@ -458,59 +458,49 @@
         MediaRoute2Info routeToCreateSessionWith = routes.get(ROUTE_ID1);
         assertNotNull(routeToCreateSessionWith);
 
-        final CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
-        final CountDownLatch onSessionInfoChangedLatchForSelect = new CountDownLatch(1);
-        final CountDownLatch onSessionInfoChangedLatchForDeselect = new CountDownLatch(1);
+        final CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerUpdatedLatchForSelect = new CountDownLatch(1);
+        final CountDownLatch onControllerUpdatedLatchForDeselect = new CountDownLatch(1);
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with ROUTE_ID1
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 assertNotNull(controller);
                 assertTrue(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
                 controllers.add(controller);
-                onSessionCreatedLatch.countDown();
+                onControllerCreatedLatch.countDown();
             }
 
             @Override
-            public void onSessionInfoChanged(RoutingController controller,
-                    RoutingSessionInfo oldInfo, RoutingSessionInfo newInfo) {
-                if (onSessionCreatedLatch.getCount() != 0
+            public void onControllerUpdated(RoutingController controller) {
+                if (onControllerCreatedLatch.getCount() != 0
                         || !TextUtils.equals(
-                                controllers.get(0).getSessionId(), controller.getSessionId())) {
+                                controllers.get(0).getId(), controller.getId())) {
                     return;
                 }
 
-                if (onSessionInfoChangedLatchForSelect.getCount() != 0) {
-                    // Check oldInfo
-                    assertEquals(controller.getSessionId(), oldInfo.getId());
-                    assertEquals(1, oldInfo.getSelectedRoutes().size());
-                    assertTrue(oldInfo.getSelectedRoutes().contains(ROUTE_ID1));
-                    assertTrue(oldInfo.getSelectableRoutes().contains(
-                            ROUTE_ID4_TO_SELECT_AND_DESELECT));
+                if (onControllerUpdatedLatchForSelect.getCount() != 0) {
+                    assertEquals(2, controller.getSelectedRoutes().size());
+                    assertTrue(getRouteIds(controller.getSelectedRoutes())
+                            .contains(ROUTE_ID1));
+                    assertTrue(getRouteIds(controller.getSelectedRoutes())
+                            .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
+                    assertFalse(getRouteIds(controller.getSelectableRoutes())
+                            .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
 
-                    // Check newInfo
-                    assertEquals(controller.getSessionId(), newInfo.getId());
-                    assertEquals(2, newInfo.getSelectedRoutes().size());
-                    assertTrue(newInfo.getSelectedRoutes().contains(ROUTE_ID1));
-                    assertTrue(newInfo.getSelectedRoutes().contains(
-                            ROUTE_ID4_TO_SELECT_AND_DESELECT));
-                    assertFalse(newInfo.getSelectableRoutes().contains(
-                            ROUTE_ID4_TO_SELECT_AND_DESELECT));
-
-                    onSessionInfoChangedLatchForSelect.countDown();
+                    onControllerUpdatedLatchForSelect.countDown();
                 } else {
-                    // Check newInfo
-                    assertEquals(controller.getSessionId(), newInfo.getId());
-                    assertEquals(1, newInfo.getSelectedRoutes().size());
-                    assertTrue(newInfo.getSelectedRoutes().contains(ROUTE_ID1));
-                    assertFalse(newInfo.getSelectedRoutes().contains(
-                            ROUTE_ID4_TO_SELECT_AND_DESELECT));
-                    assertTrue(newInfo.getSelectableRoutes().contains(
-                            ROUTE_ID4_TO_SELECT_AND_DESELECT));
+                    assertEquals(1, controller.getSelectedRoutes().size());
+                    assertTrue(getRouteIds(controller.getSelectedRoutes())
+                            .contains(ROUTE_ID1));
+                    assertFalse(getRouteIds(controller.getSelectedRoutes())
+                            .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
+                    assertTrue(getRouteIds(controller.getSelectableRoutes())
+                            .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
 
-                    onSessionInfoChangedLatchForDeselect.countDown();
+                    onControllerUpdatedLatchForDeselect.countDown();
                 }
             }
         };
@@ -520,9 +510,9 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(routeToCreateSessionWith);
-            assertTrue(onSessionCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(routeToCreateSessionWith);
+            assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             assertEquals(1, controllers.size());
             RoutingController controller = controllers.get(0);
@@ -535,15 +525,15 @@
             assertNotNull(routeToSelectAndDeselect);
 
             controller.selectRoute(routeToSelectAndDeselect);
-            assertTrue(onSessionInfoChangedLatchForSelect.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(onControllerUpdatedLatchForSelect.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             controller.deselectRoute(routeToSelectAndDeselect);
-            assertTrue(onSessionInfoChangedLatchForDeselect.await(
+            assertTrue(onControllerUpdatedLatchForDeselect.await(
                     TIMEOUT_MS, TimeUnit.MILLISECONDS));
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
@@ -556,43 +546,35 @@
         MediaRoute2Info routeToCreateSessionWith = routes.get(ROUTE_ID1);
         assertNotNull(routeToCreateSessionWith);
 
-        final CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
-        final CountDownLatch onSessionInfoChangedLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerUpdatedLatch = new CountDownLatch(1);
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with ROUTE_ID1
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 assertNotNull(controller);
                 assertTrue(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
                 controllers.add(controller);
-                onSessionCreatedLatch.countDown();
+                onControllerCreatedLatch.countDown();
             }
 
             @Override
-            public void onSessionInfoChanged(RoutingController controller,
-                    RoutingSessionInfo oldInfo, RoutingSessionInfo newInfo) {
-                if (onSessionCreatedLatch.getCount() != 0
+            public void onControllerUpdated(RoutingController controller) {
+                if (onControllerCreatedLatch.getCount() != 0
                         || !TextUtils.equals(
-                                controllers.get(0).getSessionId(), controller.getSessionId())) {
+                                controllers.get(0).getId(), controller.getId())) {
                     return;
                 }
+                assertEquals(1, controller.getSelectedRoutes().size());
+                assertFalse(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
+                assertTrue(getRouteIds(controller.getSelectedRoutes())
+                        .contains(ROUTE_ID5_TO_TRANSFER_TO));
+                assertFalse(getRouteIds(controller.getTransferrableRoutes())
+                        .contains(ROUTE_ID5_TO_TRANSFER_TO));
 
-                // Check oldInfo
-                assertEquals(controller.getSessionId(), oldInfo.getId());
-                assertEquals(1, oldInfo.getSelectedRoutes().size());
-                assertTrue(oldInfo.getSelectedRoutes().contains(ROUTE_ID1));
-                assertTrue(oldInfo.getTransferrableRoutes().contains(ROUTE_ID5_TO_TRANSFER_TO));
-
-                // Check newInfo
-                assertEquals(controller.getSessionId(), newInfo.getId());
-                assertEquals(1, newInfo.getSelectedRoutes().size());
-                assertFalse(newInfo.getSelectedRoutes().contains(ROUTE_ID1));
-                assertTrue(newInfo.getSelectedRoutes().contains(ROUTE_ID5_TO_TRANSFER_TO));
-                assertFalse(newInfo.getTransferrableRoutes().contains(ROUTE_ID5_TO_TRANSFER_TO));
-
-                onSessionInfoChangedLatch.countDown();
+                onControllerUpdatedLatch.countDown();
             }
         };
 
@@ -601,9 +583,9 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(routeToCreateSessionWith);
-            assertTrue(onSessionCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(routeToCreateSessionWith);
+            assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             assertEquals(1, controllers.size());
             RoutingController controller = controllers.get(0);
@@ -615,18 +597,18 @@
             assertNotNull(routeToTransferTo);
 
             controller.transferToRoute(routeToTransferTo);
-            assertTrue(onSessionInfoChangedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(onControllerUpdatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
-    // TODO: Add tests for onSessionReleased() call.
+    // TODO: Add tests for onSessionReleased() when provider releases the session.
 
     @Test
-    public void testRoutingControllerReleaseShouldIgnoreTransferTo() throws Exception {
+    public void testRoutingControllerRelease() throws Exception {
         final List<String> sampleRouteType = new ArrayList<>();
         sampleRouteType.add(FEATURE_SAMPLE);
 
@@ -634,29 +616,37 @@
         MediaRoute2Info routeToCreateSessionWith = routes.get(ROUTE_ID1);
         assertNotNull(routeToCreateSessionWith);
 
-        final CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
-        final CountDownLatch onSessionInfoChangedLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerUpdatedLatch = new CountDownLatch(1);
+        final CountDownLatch onControllerReleasedLatch = new CountDownLatch(1);
         final List<RoutingController> controllers = new ArrayList<>();
 
         // Create session with ROUTE_ID1
-        SessionCallback sessionCallback = new SessionCallback() {
+        RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(RoutingController controller) {
+            public void onControllerCreated(RoutingController controller) {
                 assertNotNull(controller);
                 assertTrue(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
                 controllers.add(controller);
-                onSessionCreatedLatch.countDown();
+                onControllerCreatedLatch.countDown();
             }
 
             @Override
-            public void onSessionInfoChanged(RoutingController controller,
-                    RoutingSessionInfo oldInfo, RoutingSessionInfo newInfo) {
-                if (onSessionCreatedLatch.getCount() != 0
-                        || !TextUtils.equals(
-                                controllers.get(0).getSessionId(), controller.getSessionId())) {
+            public void onControllerUpdated(RoutingController controller) {
+                if (onControllerCreatedLatch.getCount() != 0
+                        || !TextUtils.equals(controllers.get(0).getId(), controller.getId())) {
                     return;
                 }
-                onSessionInfoChangedLatch.countDown();
+                onControllerUpdatedLatch.countDown();
+            }
+
+            @Override
+            public void onControllerReleased(RoutingController controller) {
+                if (onControllerCreatedLatch.getCount() != 0
+                        || !TextUtils.equals(controllers.get(0).getId(), controller.getId())) {
+                    return;
+                }
+                onControllerReleasedLatch.countDown();
             }
         };
 
@@ -665,9 +655,9 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
 
         try {
-            mRouter2.registerSessionCallback(mExecutor, sessionCallback);
-            mRouter2.requestCreateSession(routeToCreateSessionWith);
-            assertTrue(onSessionCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            mRouter2.registerControllerCallback(mExecutor, controllerCallback);
+            mRouter2.requestCreateController(routeToCreateSessionWith);
+            assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
 
             assertEquals(1, controllers.size());
             RoutingController controller = controllers.get(0);
@@ -684,14 +674,25 @@
             // This call should be ignored.
             // The onSessionInfoChanged() shouldn't be called.
             controller.transferToRoute(routeToTransferTo);
-            assertFalse(onSessionInfoChangedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertFalse(onControllerUpdatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+            // onControllerReleased should be called.
+            assertTrue(onControllerReleasedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         } finally {
             releaseControllers(controllers);
             mRouter2.unregisterRouteCallback(routeCallback);
-            mRouter2.unregisterSessionCallback(sessionCallback);
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
     }
 
+    // TODO: Consider adding tests with bluetooth connection/disconnection.
+    @Test
+    public void testGetSystemController() {
+        final RoutingController systemController = mRouter2.getSystemController();
+        assertNotNull(systemController);
+        assertFalse(systemController.isReleased());
+    }
+
     // Helper for getting routes easily
     static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
         Map<String, MediaRoute2Info> routeMap = new HashMap<>();
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index cba8452..7726e90 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -28,7 +28,7 @@
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2;
 import android.media.MediaRouter2.RouteCallback;
-import android.media.MediaRouter2.SessionCallback;
+import android.media.MediaRouter2.RoutingControllerCallback;
 import android.media.MediaRouter2Manager;
 import android.media.RouteDiscoveryPreference;
 import android.media.RoutingSessionInfo;
@@ -110,7 +110,7 @@
 
     private final List<MediaRouter2Manager.Callback> mManagerCallbacks = new ArrayList<>();
     private final List<RouteCallback> mRouteCallbacks = new ArrayList<>();
-    private final List<SessionCallback> mSessionCallbacks = new ArrayList<>();
+    private final List<RoutingControllerCallback> mControllerCallbacks = new ArrayList<>();
 
     public static final List<String> FEATURES_ALL = new ArrayList();
     public static final List<String> FEATURES_SPECIAL = new ArrayList();
@@ -213,9 +213,9 @@
         addManagerCallback(new MediaRouter2Manager.Callback());
         //TODO: remove this when it's not necessary.
         addRouterCallback(new MediaRouter2.RouteCallback());
-        addSessionCallback(new SessionCallback() {
+        addSessionCallback(new RoutingControllerCallback() {
             @Override
-            public void onSessionCreated(MediaRouter2.RoutingController controller) {
+            public void onControllerCreated(MediaRouter2.RoutingController controller) {
                 if (createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1)) {
                     latch.countDown();
                 }
@@ -227,7 +227,7 @@
 
         mManager.selectRoute(mPackageName, routeToSelect);
         assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertEquals(1, mManager.getActiveSessions().size());
+        assertEquals(2, mManager.getActiveSessions().size());
     }
 
     @Test
@@ -414,9 +414,9 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
     }
 
-    private void addSessionCallback(SessionCallback sessionCallback) {
-        mSessionCallbacks.add(sessionCallback);
-        mRouter2.registerSessionCallback(mExecutor, sessionCallback);
+    private void addSessionCallback(RoutingControllerCallback controllerCallback) {
+        mControllerCallbacks.add(controllerCallback);
+        mRouter2.registerControllerCallback(mExecutor, controllerCallback);
     }
 
     private void clearCallbacks() {
@@ -430,10 +430,10 @@
         }
         mRouteCallbacks.clear();
 
-        for (SessionCallback sessionCallback : mSessionCallbacks) {
-            mRouter2.unregisterSessionCallback(sessionCallback);
+        for (RoutingControllerCallback controllerCallback : mControllerCallbacks) {
+            mRouter2.unregisterControllerCallback(controllerCallback);
         }
-        mSessionCallbacks.clear();
+        mControllerCallbacks.clear();
     }
 
     private void releaseAllSessions() {
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 9d93c9b..0c6f507 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -47,7 +47,6 @@
         "sensor.cpp",
         "sharedmem.cpp",
         "storage_manager.cpp",
-        "surface_texture.cpp",
         "surface_control.cpp",
         "system_fonts.cpp",
         "trace.cpp",
@@ -70,6 +69,8 @@
         "libnetd_client",
         "libhwui",
         "libxml2",
+        "libEGL",
+        "libGLESv2",
         "android.hardware.configstore@1.0",
         "android.hardware.configstore-utils",
     ],
diff --git a/native/android/surface_texture.cpp b/native/android/surface_texture.cpp
deleted file mode 100644
index 3049ec1..0000000
--- a/native/android/surface_texture.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/surface_texture.h>
-#include <android/surface_texture_jni.h>
-
-#define LOG_TAG "ASurfaceTexture"
-
-#include <utils/Log.h>
-
-#include <gui/Surface.h>
-
-#include <gui/surfacetexture/surface_texture_platform.h>
-
-#include <android_runtime/android_graphics_SurfaceTexture.h>
-
-using namespace android;
-
-ASurfaceTexture* ASurfaceTexture_fromSurfaceTexture(JNIEnv* env, jobject surfacetexture) {
-    if (!surfacetexture || !android_SurfaceTexture_isInstanceOf(env, surfacetexture)) {
-        return nullptr;
-    }
-    auto consumer = SurfaceTexture_getSurfaceTexture(env, surfacetexture);
-    auto producer = SurfaceTexture_getProducer(env, surfacetexture);
-    return ASurfaceTexture_create(consumer, producer);
-}
-
-ANativeWindow* ASurfaceTexture_acquireANativeWindow(ASurfaceTexture* st) {
-    sp<Surface> surface = new Surface(st->producer);
-    ANativeWindow* win(surface.get());
-    ANativeWindow_acquire(win);
-    return win;
-}
-
-void ASurfaceTexture_release(ASurfaceTexture* st) {
-    delete st;
-}
-
-int ASurfaceTexture_attachToGLContext(ASurfaceTexture* st, uint32_t tex) {
-    return st->consumer->attachToContext(tex);
-}
-
-int ASurfaceTexture_detachFromGLContext(ASurfaceTexture* st) {
-    return st->consumer->detachFromContext();
-}
-
-int ASurfaceTexture_updateTexImage(ASurfaceTexture* st) {
-    return st->consumer->updateTexImage();
-}
-
-void ASurfaceTexture_getTransformMatrix(ASurfaceTexture* st, float mtx[16]) {
-    st->consumer->getTransformMatrix(mtx);
-}
-
-int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture* st) {
-    return st->consumer->getTimestamp();
-}
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index 26c7f8d..ea8a521 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <android/bitmap.h>
+#include <android/data_space.h>
 #include <android/graphics/bitmap.h>
 #include <android/data_space.h>
 
@@ -74,3 +75,20 @@
     ABitmap_releaseRef(bitmap.get());
     return ANDROID_BITMAP_RESULT_SUCCESS;
 }
+
+int AndroidBitmap_compress(const AndroidBitmapInfo* info,
+                           int32_t dataSpace,
+                           const void* pixels,
+                           int32_t format, int32_t quality,
+                           void* userContext,
+                           AndroidBitmap_compress_write_fn fn) {
+    if (NULL == info || NULL == pixels || NULL == fn) {
+        return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+    }
+    if (quality < 0 || quality > 100) {
+        return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+    }
+
+    return ABitmap_compress(info, (ADataSpace) dataSpace, pixels,
+            (AndroidBitmapCompressFormat) format, quality, userContext, fn);
+}
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index 2ef203d..5143967 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -225,13 +225,12 @@
 
 int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) {
     if (!info) {
-        // FIXME: Better invalid?
-        return -1;
+        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
     switch (toDecoder(info)->mCodec->getInfo().alphaType()) {
         case kUnknown_SkAlphaType:
             LOG_ALWAYS_FATAL("Invalid alpha type");
-            return -1;
+            return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
         case kUnpremul_SkAlphaType:
             // fall through. premul is the default.
         case kPremul_SkAlphaType:
@@ -241,26 +240,12 @@
     }
 }
 
-SkAlphaType toAlphaType(int androidBitmapFlags) {
-    switch (androidBitmapFlags) {
-        case ANDROID_BITMAP_FLAGS_ALPHA_PREMUL:
-            return kPremul_SkAlphaType;
-        case ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL:
-            return kUnpremul_SkAlphaType;
-        case ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE:
-            return kOpaque_SkAlphaType;
-        default:
-            return kUnknown_SkAlphaType;
-    }
-}
-
-int AImageDecoder_setAlphaFlags(AImageDecoder* decoder, int alphaFlag) {
-    if (!decoder || alphaFlag < ANDROID_BITMAP_FLAGS_ALPHA_PREMUL
-            || alphaFlag > ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL) {
+int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* decoder, bool required) {
+    if (!decoder) {
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
 
-    return toDecoder(decoder)->setOutAlphaType(toAlphaType(alphaFlag))
+    return toDecoder(decoder)->setUnpremultipliedRequired(required)
             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
 }
 
diff --git a/native/graphics/jni/libjnigraphics.map.txt b/native/graphics/jni/libjnigraphics.map.txt
index 832770f..6843e7a 100644
--- a/native/graphics/jni/libjnigraphics.map.txt
+++ b/native/graphics/jni/libjnigraphics.map.txt
@@ -1,26 +1,27 @@
 LIBJNIGRAPHICS {
   global:
-    AImageDecoder_createFromAAsset;
-    AImageDecoder_createFromFd;
-    AImageDecoder_createFromBuffer;
-    AImageDecoder_delete;
-    AImageDecoder_setAndroidBitmapFormat;
-    AImageDecoder_setAlphaFlags;
-    AImageDecoder_getHeaderInfo;
-    AImageDecoder_getMinimumStride;
-    AImageDecoder_decodeImage;
-    AImageDecoder_setTargetSize;
-    AImageDecoder_setCrop;
-    AImageDecoderHeaderInfo_getWidth;
-    AImageDecoderHeaderInfo_getHeight;
-    AImageDecoderHeaderInfo_getMimeType;
-    AImageDecoderHeaderInfo_getAlphaFlags;
-    AImageDecoderHeaderInfo_isAnimated;
-    AImageDecoderHeaderInfo_getAndroidBitmapFormat;
+    AImageDecoder_createFromAAsset; # introduced=30
+    AImageDecoder_createFromFd; # introduced=30
+    AImageDecoder_createFromBuffer; # introduced=30
+    AImageDecoder_delete; # introduced=30
+    AImageDecoder_setAndroidBitmapFormat; # introduced=30
+    AImageDecoder_setUnpremultipliedRequired; # introduced=30
+    AImageDecoder_getHeaderInfo; # introduced=30
+    AImageDecoder_getMinimumStride; # introduced=30
+    AImageDecoder_decodeImage; # introduced=30
+    AImageDecoder_setTargetSize; # introduced=30
+    AImageDecoder_setCrop; # introduced=30
+    AImageDecoderHeaderInfo_getWidth; # introduced=30
+    AImageDecoderHeaderInfo_getHeight; # introduced=30
+    AImageDecoderHeaderInfo_getMimeType; # introduced=30
+    AImageDecoderHeaderInfo_getAlphaFlags; # introduced=30
+    AImageDecoderHeaderInfo_isAnimated; # introduced=30
+    AImageDecoderHeaderInfo_getAndroidBitmapFormat; # introduced=30
     AndroidBitmap_getInfo;
     AndroidBitmap_getDataSpace;
     AndroidBitmap_lockPixels;
     AndroidBitmap_unlockPixels;
+    AndroidBitmap_compress; # introduced=30
   local:
     *;
 };
diff --git a/packages/CarSystemUI/res/layout/super_notification_shade.xml b/packages/CarSystemUI/res/layout/super_notification_shade.xml
new file mode 100644
index 0000000..3fe1ea3
--- /dev/null
+++ b/packages/CarSystemUI/res/layout/super_notification_shade.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<!-- This is the notification shade window. -->
+<com.android.systemui.statusbar.phone.NotificationShadeWindowView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true">
+
+    <com.android.systemui.statusbar.BackDropView
+        android:id="@+id/backdrop"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone"
+        sysui:ignoreRightInset="true"
+    >
+        <ImageView android:id="@+id/backdrop_back"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"/>
+        <ImageView android:id="@+id/backdrop_front"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"
+            android:visibility="invisible"/>
+    </com.android.systemui.statusbar.BackDropView>
+
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_for_bubble"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+    />
+
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_behind"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+    />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/status_bar_height"
+        android:orientation="vertical"
+    >
+        <FrameLayout
+            android:id="@+id/status_bar_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+        />
+
+        <FrameLayout
+            android:id="@+id/car_top_navigation_bar_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+    </LinearLayout>
+
+    <include layout="@layout/brightness_mirror"/>
+
+    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout="@layout/car_fullscreen_user_switcher"/>
+
+    <include layout="@layout/notification_center_activity"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginBottom="@dimen/navigation_bar_height"
+        android:visibility="invisible"/>
+
+    <include layout="@layout/headsup_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible"/>
+
+    <include layout="@layout/status_bar_expanded"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible"/>
+
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_in_front"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+    />
+
+</com.android.systemui.statusbar.phone.NotificationShadeWindowView>
diff --git a/packages/CarSystemUI/res/layout/super_status_bar.xml b/packages/CarSystemUI/res/layout/super_status_bar.xml
index 0b34626..c7b22f8 100644
--- a/packages/CarSystemUI/res/layout/super_status_bar.xml
+++ b/packages/CarSystemUI/res/layout/super_status_bar.xml
@@ -1,21 +1,23 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+**
+** 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.
+*/
+-->
 
-<!-- This is the combined status bar / notification panel window. -->
+<!-- This is the status bar window. -->
 <com.android.systemui.statusbar.phone.StatusBarWindowView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
@@ -23,87 +25,9 @@
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">
 
-    <com.android.systemui.statusbar.BackDropView
-        android:id="@+id/backdrop"
+    <FrameLayout
+        android:id="@+id/status_bar_container"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone"
-        sysui:ignoreRightInset="true"
-    >
-        <ImageView android:id="@+id/backdrop_back"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:scaleType="centerCrop"/>
-        <ImageView android:id="@+id/backdrop_front"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:scaleType="centerCrop"
-            android:visibility="invisible"/>
-    </com.android.systemui.statusbar.BackDropView>
-
-    <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_for_bubble"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        sysui:ignoreRightInset="true"
-    />
-
-    <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_behind"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        sysui:ignoreRightInset="true"
-    />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/status_bar_height"
-        android:orientation="vertical"
-    >
-        <FrameLayout
-            android:id="@+id/status_bar_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
-        />
-
-        <FrameLayout
-            android:id="@+id/car_top_navigation_bar_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
-    </LinearLayout>
-
-    <include layout="@layout/brightness_mirror"/>
-
-    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout="@layout/car_fullscreen_user_switcher"/>
-
-    <include layout="@layout/notification_center_activity"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginBottom="@dimen/navigation_bar_height"
-        android:visibility="invisible"/>
-
-    <include layout="@layout/headsup_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="invisible"/>
-
-    <include layout="@layout/status_bar_expanded"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="invisible"/>
-
-    <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_in_front"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        sysui:ignoreRightInset="true"
-    />
+        android:layout_height="wrap_content" />
 
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/CarSystemUI/res/xml/overlayable.xml b/packages/CarSystemUI/res/xml/overlayable.xml
new file mode 100644
index 0000000..2b6e66e
--- /dev/null
+++ b/packages/CarSystemUI/res/xml/overlayable.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <overlayable name="SystemBarsLayouts">
+        <policy type="product|signature">
+            <item type="layout" name="car_navigation_bar" />
+        </policy>
+    </overlayable>
+</resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
index d8c9d17..78764dd 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
@@ -235,7 +235,7 @@
 
     private void buildNavBarWindows() {
         mTopNavigationBarWindow = mSuperStatusBarViewFactory
-                .getStatusBarWindowView()
+                .getNotificationShadeWindowView()
                 .findViewById(R.id.car_top_navigation_bar_container);
         mBottomNavigationBarWindow = mCarNavigationBarController.getBottomWindow();
         mLeftNavigationBarWindow = mCarNavigationBarController.getLeftWindow();
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarShadeControllerImpl.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarShadeControllerImpl.java
index d1d352a..755ed25 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarShadeControllerImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarShadeControllerImpl.java
@@ -24,10 +24,10 @@
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ShadeControllerImpl;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -41,13 +41,13 @@
     @Inject
     public CarShadeControllerImpl(CommandQueue commandQueue,
             StatusBarStateController statusBarStateController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             WindowManager windowManager,
             Lazy<StatusBar> statusBarLazy,
             Lazy<AssistManager> assistManagerLazy,
             Lazy<BubbleController> bubbleControllerLazy) {
-        super(commandQueue, statusBarStateController, statusBarWindowController,
+        super(commandQueue, statusBarStateController, notificationShadeWindowController,
                 statusBarKeyguardViewManager, windowManager,
                 statusBarLazy, assistManagerLazy, bubbleControllerLazy);
     }
@@ -61,14 +61,14 @@
             return;
         }
 
-        mStatusBarWindowController.setStatusBarFocusable(false);
-        getCarStatusBar().getStatusBarWindowViewController().cancelExpandHelper();
+        mNotificationShadeWindowController.setNotificationShadeFocusable(false);
+        getCarStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();
         getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor);
 
         getCarStatusBar().animateNotificationPanel(getCarStatusBar().getClosingVelocity(), true);
 
         if (!getCarStatusBar().isTracking()) {
-            mStatusBarWindowController.setPanelVisible(false);
+            mNotificationShadeWindowController.setPanelVisible(false);
             getCarNotificationView().setVisibility(View.INVISIBLE);
         }
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 18485dc..76e9ec6 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -126,13 +126,13 @@
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -303,7 +303,7 @@
             Lazy<AssistManager> assistManagerLazy,
             NotificationListener notificationListener,
             ConfigurationController configurationController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
@@ -391,7 +391,7 @@
                 assistManagerLazy,
                 notificationListener,
                 configurationController,
-                statusBarWindowController,
+                notificationShadeWindowController,
                 lockscreenLockIconController,
                 dozeParameters,
                 scrimController,
@@ -545,7 +545,7 @@
         mNotificationPanelBackground = getDefaultWallpaper();
         mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
 
-        FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
+        FragmentHostManager manager = FragmentHostManager.get(mPhoneStatusBarWindow);
         manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
             mBatteryMeterView = fragment.getView().findViewById(R.id.battery);
 
@@ -646,9 +646,9 @@
         carNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper,
                 carHeadsUpNotificationManager, mNotificationDataManager);
 
-        mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view);
-        View glassPane = mStatusBarWindow.findViewById(R.id.glass_pane);
-        mHandleBar = mStatusBarWindow.findViewById(R.id.handle_bar);
+        final View glassPane = mNotificationShadeWindowView.findViewById(R.id.glass_pane);
+        mNotificationView = mNotificationShadeWindowView.findViewById(R.id.notification_view);
+        mHandleBar = mNotificationShadeWindowView.findViewById(R.id.handle_bar);
         mNotificationView.setClickHandlerFactory(mNotificationClickHandlerFactory);
         mNotificationView.setNotificationDataManager(mNotificationDataManager);
 
@@ -779,7 +779,7 @@
         }
         // scroll to top
         mNotificationList.scrollToPosition(0);
-        mStatusBarWindowController.setPanelVisible(true);
+        mNotificationShadeWindowController.setPanelVisible(true);
         mNotificationView.setVisibility(View.VISIBLE);
         animateNotificationPanel(mOpeningVelocity, false);
 
@@ -863,7 +863,7 @@
                 mOpeningVelocity = DEFAULT_FLING_VELOCITY;
                 mClosingVelocity = DEFAULT_FLING_VELOCITY;
                 if (isClosing) {
-                    mStatusBarWindowController.setPanelVisible(false);
+                    mNotificationShadeWindowController.setPanelVisible(false);
                     mNotificationView.setVisibility(View.INVISIBLE);
                     mNotificationView.setClipBounds(null);
                     mNotificationViewController.onVisibilityChanged(false);
@@ -1128,7 +1128,7 @@
                 // when the on-scroll is called for the first time to open.
                 mNotificationList.scrollToPosition(0);
             }
-            mStatusBarWindowController.setPanelVisible(true);
+            mNotificationShadeWindowController.setPanelVisible(true);
             mNotificationView.setVisibility(View.VISIBLE);
 
             // clips the view for the notification shade when the user scrolls to open.
@@ -1294,7 +1294,7 @@
         @Override
         protected View createHeadsUpPanel() {
             // In SystemUi the view is already in the window so just return a reference.
-            return mStatusBarWindow.findViewById(R.id.notification_headsup);
+            return mNotificationShadeWindowView.findViewById(R.id.notification_headsup);
         }
 
         @Override
@@ -1320,7 +1320,7 @@
 
             super.setHeadsUpVisible();
             if (mHeadsUpPanel.getVisibility() == View.VISIBLE) {
-                mStatusBarWindowController.setHeadsUpShowing(true);
+                mNotificationShadeWindowController.setHeadsUpShowing(true);
                 mStatusBarWindowController.setForceStatusBarVisible(true);
             }
         }
@@ -1330,7 +1330,7 @@
             super.removeNotificationFromPanel(currentHeadsUpNotification);
             // If the panel ended up empty and hidden we can remove it from SystemUi
             if (mHeadsUpPanel.getVisibility() != View.VISIBLE) {
-                mStatusBarWindowController.setHeadsUpShowing(false);
+                mNotificationShadeWindowController.setHeadsUpShowing(false);
                 mStatusBarWindowController.setForceStatusBarVisible(false);
             }
         }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index 2a2eb69..59f9f94 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -28,8 +28,8 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
@@ -53,14 +53,14 @@
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             NavigationModeController navigationModeController,
             DockManager dockManager,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController,
             NotificationMediaManager notificationMediaManager,
             CarNavigationBarController carNavigationBarController,
             FullscreenUserSwitcher fullscreenUserSwitcher) {
         super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
                 configurationController, keyguardUpdateMonitor, navigationModeController,
-                dockManager, statusBarWindowController, keyguardStateController,
+                dockManager, notificationShadeWindowController, keyguardStateController,
                 notificationMediaManager);
         mShouldHideNavBar = context.getResources()
                 .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index 3abbe32..45da822 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -85,12 +85,12 @@
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -173,7 +173,7 @@
             Lazy<AssistManager> assistManagerLazy,
             NotificationListener notificationListener,
             ConfigurationController configurationController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
@@ -260,7 +260,7 @@
                 assistManagerLazy,
                 notificationListener,
                 configurationController,
-                statusBarWindowController,
+                notificationShadeWindowController,
                 lockscreenLockIconController,
                 dozeParameters,
                 scrimController,
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index 421526b..a099147 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -62,7 +62,7 @@
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"Tekuća deinstaliranja"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspjela deinstaliranja"</string>
     <string name="uninstalling" msgid="8709566347688966845">"Deinstaliranje..."</string>
-    <string name="uninstalling_app" msgid="8866082646836981397">"Deinstaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Deinstaliran je paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspjelo."</string>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index 61ff87f..822c548 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -24,8 +24,8 @@
     <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнотулууда…"</string>
     <string name="install_done" msgid="5987363587661783896">"Колдонмо орнотулду."</string>
     <string name="install_confirm_question" msgid="8176284075816604590">"Бул колдонмону орнотоюн деп жатасызбы?"</string>
-    <string name="install_confirm_question_update" msgid="7942235418781274635">"Учурдагы колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайындарыңыз өчүрүлбөйт."</string>
-    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Учурдагы алдын ала орнотулган колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайындарыңыз өчүрүлбөйт."</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Учурдагы колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайын-даректериңиз өчүрүлбөйт."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Учурдагы алдын ала орнотулган колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайын-даректериңиз өчүрүлбөйт."</string>
     <string name="install_failed" msgid="5777824004474125469">"Колдонмо орнотулган жок."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Топтомду орнотууга болбойт."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
@@ -83,9 +83,9 @@
     <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Коопсуздукту сактоо максатында, планшетиңизге бул булактан колдонмолорду орнотууга уруксат жок."</string>
     <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Коопсуздукту сактоо максатында, сыналгыңызга бул булактан колдонмолорду орнотууга уруксат жок."</string>
     <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Коопсуздукту сактоо максатында, телефонуңузга бул булактан колдонмолорду орнотууга уруксат жок."</string>
-    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонуңуз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Планшетиңиз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Сыналгыңыз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам сыналгыңызга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонуңуз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Планшетиңиз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Сыналгыңыз жана жеке дайын-даректериңиз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам сыналгыңызга кандайдыр бир зыян келтирилсе же дайын-даректериңизды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"Улантуу"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"Жөндөөлөр"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"Тагынма колдонмолорду орнотуу/чыгаруу"</string>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index 7b50547..5ce30c2 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -62,7 +62,7 @@
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktywne odinstalowania"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nieudane odinstalowania"</string>
     <string name="uninstalling" msgid="8709566347688966845">"Odinstalowuję…"</string>
-    <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalowuję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalowuję <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Odinstalowywanie zakończone."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Odinstalowano pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Nie udało się odinstalować."</string>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index a0702d6..c123d69 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -53,7 +53,7 @@
     <string name="uninstall_application_title" msgid="4045420072401428123">"Odstrani aplikacijo"</string>
     <string name="uninstall_update_title" msgid="824411791011583031">"Odstrani posodobitev"</string>
     <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je del te aplikacije:"</string>
-    <string name="uninstall_application_text" msgid="3816830743706143980">"Ali želite odstraniti to aplikacijo?"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Ali želite odmestiti to aplikacijo?"</string>
     <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Ali želite odstraniti aplikacijo za "<b>"vse"</b>" uporabnike? Aplikacija in njeni podatki bodo odstranjeni iz "<b>"vseh"</b>" uporabnikov v napravi."</string>
     <string name="uninstall_application_text_user" msgid="498072714173920526">"Ali želite to aplikacijo odstraniti za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
     <string name="uninstall_update_text" msgid="863648314632448705">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki."</string>
@@ -62,11 +62,11 @@
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"Odstranitve v teku"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspele odstranitve"</string>
     <string name="uninstalling" msgid="8709566347688966845">"Odstranjevanje …"</string>
-    <string name="uninstalling_app" msgid="8866082646836981397">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Odstranitev je končana."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Odstranitev ni uspela."</string>
-    <string name="uninstall_failed_app" msgid="5506028705017601412">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
     <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktivne skrbniške aplikacije naprave ni mogoče odstraniti"</string>
     <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Aktivne skrbniške aplikacije za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g> ni mogoče odstraniti"</string>
     <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Aplikacija je obvezna za nekatere uporabnike/profile in je odstranjena za druge."</string>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 5636cc8..de4817c 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -85,6 +85,7 @@
         Settings.Secure.TTY_MODE_ENABLED,
         Settings.Secure.RTT_CALLING_MODE,
         Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+        Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED,
         Settings.Secure.NIGHT_DISPLAY_CUSTOM_START_TIME,
         Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
         Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index ed06fa7..849f22f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -131,6 +131,7 @@
         VALIDATORS.put(
                 Secure.INCALL_POWER_BUTTON_BEHAVIOR,
                 new DiscreteValueValidator(new String[] {"1", "2"}));
+        VALIDATORS.put(Secure.MINIMAL_POST_PROCESSING_ALLOWED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 449a135..f6e5062 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1999,6 +1999,9 @@
         dumpSetting(s, p,
                 Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
                 SecureSettingsProto.Doze.PULSE_ON_TAP);
+        dumpSetting(s, p,
+                Settings.Secure.SUPPRESS_DOZE,
+                SecureSettingsProto.Doze.SUPPRESS);
         p.end(dozeToken);
 
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index a337570..b896a2a 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -726,7 +726,8 @@
                  Settings.Secure.FACE_UNLOCK_RE_ENROLL,
                  Settings.Secure.TAP_GESTURE,
                  Settings.Secure.WINDOW_MAGNIFICATION,
-                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER);
+                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
+                 Settings.Secure.SUPPRESS_DOZE);
 
     @Test
     public void systemSettingsBackedUpOrBlacklisted() {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 1c63efc..fb9bc52 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -221,7 +221,10 @@
     <!-- Permission required for CTS test - UiModeManagerTest -->
     <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
 
-      <!-- Permission required for CTS test - CarModeInCallServiceTest -->
+    <!-- Permission required for CTS test - SystemConfigTest -->
+    <uses-permission android:name="android.permission.READ_CARRIER_APP_INFO"/>
+
+    <!-- Permission required for CTS test - CarModeInCallServiceTest -->
     <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
 
     <!-- Permission requried for CTS test - CellBroadcastIntentsTest -->
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 92dd9fd..8a1f6de 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Geen diens nie."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Wissel invoermetode"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Vliegtuigmodus"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN word vereis om vir opdatering voor te berei"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Patroon word vereis om vir opdatering voor te berei"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Wagwoord word vereis om vir opdatering voor te berei"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Patroon word vereis nadat toestel herbegin het"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN word vereis nadat toestel herbegin het"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Wagwoord word vereis nadat toestel herbegin het"</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index f94c20f..0a4aee5 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"ከአገልግሎት መስጫ ክልል ውጪ።"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"የግቤት ስልት ቀይር"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"የአውሮፕላን ሁነታ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ለዝማኔ ለማዘጋጀት ፒን ያስፈልጋል"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ለዝማኔ ለማዘጋጀት ሥርዓተ ጥለት ያስፈልጋል"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ለዝማኔ ለማዘጋጀት የይለፍ ቃል ያስፈልጋል"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"መሣሪያ ዳግም ከጀመረ በኋላ ሥርዓተ ጥለት ያስፈልጋል"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"መሣሪያ ዳግም ከተነሳ በኋላ ፒን ያስፈልጋል"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"መሣሪያ ዳግም ከጀመረ በኋላ የይለፍ ቃል ያስፈልጋል"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 393da27..491dc39 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -48,7 +48,7 @@
     <string name="keyguard_permanent_disabled_sim_instructions" msgid="2490584154727897806">"‏تم إيقاف شريحة SIM بشكل دائم.\n اتصل بمقدم خدمة اللاسلكي للحصول على شريحة SIM أخرى."</string>
     <string name="keyguard_sim_locked_message" msgid="4343544458476911044">"‏شريحة SIM مؤمّنة."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"‏شريحة SIM مؤمّنة برمز PUK."</string>
-    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"‏جارٍ إلغاء تأمين شريحة SIM…"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"‏جارٍ فتح قفل شريحة SIM…"</string>
     <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"منطقة رقم التعريف الشخصي"</string>
     <string name="keyguard_accessibility_password" msgid="3524161948484801450">"كلمة مرور الجهاز"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"‏منطقة رقم التعريف الشخصي لشريحة SIM"</string>
@@ -81,7 +81,7 @@
     <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"‏SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" غير مفعّلة الآن. أدخل رمز PUK للمتابعة. واتصل بمشغل شبكة الجوّال لمعرفة التفاصيل."</string>
     <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"أدخل رمز رقم التعريف الشخصي المطلوب"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"تأكيد رمز رقم التعريف الشخصي المطلوب"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"‏جارٍ إلغاء تأمين شريحة SIM…"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"‏جارٍ فتح قفل شريحة SIM…"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"اكتب رمز رقم التعريف الشخصي المكوّن من ٤ إلى ٨ أرقام."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"‏يجب أن يتضمن رمز PUK‏ ۸ أرقام أو أكثر."</string>
     <string name="kg_invalid_puk" msgid="1774337070084931186">"‏أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى إيقاف شريحة SIM نهائيًا."</string>
@@ -113,6 +113,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"لا تتوفر خدمة."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تبديل أسلوب الإدخال"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"وضع الطائرة"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"يجب إدخال رقم التعريف الشخصي للتحضير للتحديث."</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"يجب رسم النقش للتحضير للتحديث."</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"يجب إدخال كلمة المرور للتحضير للتحديث."</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"يجب رسم النقش بعد إعادة تشغيل الجهاز"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز"</string>
@@ -125,28 +128,28 @@
     <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"اختار المشرف قفل الجهاز"</string>
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"تم حظر الجهاز يدويًا"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="1337428979661197957">
-      <item quantity="zero">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد النقش.</item>
-      <item quantity="two">لم يتم إلغاء تأمين الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد النقش.</item>
-      <item quantity="few">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعات. تأكيد النقش.</item>
-      <item quantity="many">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد النقش.</item>
-      <item quantity="other">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد النقش.</item>
-      <item quantity="one">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_0">%d</xliff:g> ساعة. تأكيد النقش.</item>
+      <item quantity="zero">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد النقش.</item>
+      <item quantity="two">لم يتم فتح قفل الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد النقش.</item>
+      <item quantity="few">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعات. تأكيد النقش.</item>
+      <item quantity="many">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد النقش.</item>
+      <item quantity="other">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد النقش.</item>
+      <item quantity="one">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_0">%d</xliff:g> ساعة. تأكيد النقش.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="6444519502336330270">
-      <item quantity="zero">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
-      <item quantity="two">لم يتم إلغاء تأمين الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد رقم التعريف الشخصي.</item>
-      <item quantity="few">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
-      <item quantity="many">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
-      <item quantity="other">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
-      <item quantity="one">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_0">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
+      <item quantity="zero">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
+      <item quantity="two">لم يتم فتح قفل الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد رقم التعريف الشخصي.</item>
+      <item quantity="few">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
+      <item quantity="many">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
+      <item quantity="other">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
+      <item quantity="one">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_0">%d</xliff:g> ساعة. تأكيد رقم التعريف الشخصي.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5343961527665116914">
-      <item quantity="zero">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
-      <item quantity="two">لم يتم إلغاء تأمين الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد كلمة المرور.</item>
-      <item quantity="few">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعات. تأكيد كلمة المرور.</item>
-      <item quantity="many">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
-      <item quantity="other">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
-      <item quantity="one">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_0">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
+      <item quantity="zero">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
+      <item quantity="two">لم يتم فتح قفل الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد كلمة المرور.</item>
+      <item quantity="few">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعات. تأكيد كلمة المرور.</item>
+      <item quantity="many">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
+      <item quantity="other">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
+      <item quantity="one">لم يتم فتح قفل الجهاز لمدة <xliff:g id="NUMBER_0">%d</xliff:g> ساعة. تأكيد كلمة المرور.</item>
     </plurals>
     <string name="kg_fingerprint_not_recognized" msgid="5982606907039479545">"لم يتم التعرف عليها."</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"لم يتم التعرّف عليه."</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index 3b51e48..4367efb 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"কোনো সেৱা নাই।"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ইনপুট পদ্ধতি সলনি কৰক"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"এয়াৰপ্লেন ম\'ড"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"আপডে\'টৰ বাবে সাজু হ\'বলৈ পিনৰ আৱশ্যক"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"আপডে\'টৰ বাবে সাজু হ\'বলৈ আর্হিৰ আৱশ্যক"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"আপডে\'টৰ বাবে সাজু হ\'বলৈ পাছৱৰ্ডৰ আৱশ্যক"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত আৰ্হি দিয়াটো বাধ্যতামূলক"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পিন দিয়াটো বাধ্যতামূলক"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পাছৱৰ্ড দিয়াটো বাধ্যতামূলক"</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index d63c23f..aadd201 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Xidmət yoxdur."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Daxiletmə metoduna keçin"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Təyyarə rejimi"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Güncəlləməyə hazırlıq üçün PIN kod tələb olunur"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Güncəlləməyə hazırlıq üçün model tələb olunur"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Güncəlləməyə hazırlıq üçün parol tələb olunur"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Cihaz yenidən başladıqdan sonra model tələb olunur"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Cihaz yeniden başladıqdan sonra PIN tələb olunur"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Cihaz yeniden başladıqdan sonra parol tələb olunur"</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index e206958..656e323 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -104,6 +104,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Mreža nije dostupna."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promeni metod unosa"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Režim rada u avionu"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN je obavezan radi pripreme za ažuriranje"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Šablon je obavezan radi pripreme za ažuriranje"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Lozinka je obavezna radi pripreme za ažuriranje"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Treba da unesete šablon kada se uređaj ponovo pokrene"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Treba da unesete PIN kada se uređaj ponovo pokrene"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Treba da unesete lozinku kada se uređaj ponovo pokrene"</string>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 569e705..07b6f35 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Не абслугоўваецца."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Пераключэнне рэжыму ўводу"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Рэжым палёту"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Для падрыхтоўкі да абнаўлення неабходна ўвесці PIN-код"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Для падрыхтоўкі да абнаўлення неабходна ўвесці ўзор разблакіроўкі"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Для падрыхтоўкі да абнаўлення неабходна ўвесці пароль"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Пасля перазапуску прылады патрабуецца ўзор"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Пасля перазапуску прылады патрабуецца PIN-код"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Пасля перазапуску прылады патрабуецца пароль"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index d015be3..a8c64f5 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Няма покритие."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Превключване на метода на въвеждане"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Самолетен режим"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"За подготовката за актуализация се изисква ПИН код"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"За подготовката за актуализация се изисква фигура"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"За подготовката за актуализация се изисква парола"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"След рестартиране на устройството се изисква фигура"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"След рестартиране на устройството се изисква ПИН код"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"След рестартиране на устройството се изисква парола"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 8eae6e6..479e83a 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"কোনো পরিষেবা নেই।"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ইনপুট পদ্ধতি পরিবর্তন করুন"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"বিমান মোড"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"আপডেট প্রস্তুত করতে পিন দরকার"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"আপডেট প্রস্তুত করতে প্যাটার্ন দরকার"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"আপডেট প্রস্তুত করতে পাসওয়ার্ড দরকার"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ডিভাইসটি পুনরায় চালু হওয়ার পর প্যাটার্নের প্রয়োজন হবে"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ডিভাইসটি পুনরায় চালু হওয়ার পর পিন প্রয়োজন হবে"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ডিভাইসটি পুনরায় চালু হওয়ার পর পাসওয়ার্ডের প্রয়োজন হবে"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 286b08b..ada4c13 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -104,6 +104,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nema mreže."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promjena načina unosa"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Način rada u avionu"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Za pripremu ažuriranja potreban je PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Za pripremu ažuriranja potreban je uzorak"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Za pripremu ažuriranja potrebna je lozinka"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Potreban je uzorak nakon što se uređaj ponovo pokrene"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Potreban je PIN nakon što se uređaj ponovo pokrene"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Potrebna je lozinka nakon što se uređaj ponovo pokrene"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index cb7fa37..6f5b682 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sense servei"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Canvia el mètode d\'introducció"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Mode d\'avió"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Cal introduir el PIN per preparar l\'actualització"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Cal introduir el patró per preparar l\'actualització"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Cal introduir la contrasenya per preparar l\'actualització"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Cal introduir el patró quan es reinicia el dispositiu"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Cal introduir el PIN quan es reinicia el dispositiu"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Cal introduir la contrasenya quan es reinicia el dispositiu"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 4f0c0ff..a2f79ad 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Žádný signál"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Přepnout metodu zadávání"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Režim Letadlo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Příprava na aktualizaci vyžaduje PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Příprava na aktualizaci vyžaduje gesto"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Příprava na aktualizaci vyžaduje heslo"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po restartování zařízení je vyžadováno gesto"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po restartování zařízení je vyžadován kód PIN"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po restartování zařízení je vyžadováno heslo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index e486fc6..ef06269 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen dækning."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Skift indtastningsmetode"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Flytilstand"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Du skal angive din pinkode for at forberede opdateringen"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Du skal angive dit mønster for at forberede opdateringen"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Du skal angive din adgangskode for at forberede opdateringen"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du skal angive et mønster, når du har genstartet enheden"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Der skal angives en pinkode efter genstart af enheden"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Der skal angives en adgangskode efter genstart af enheden"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 06d012f..fdfce1f 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Dienst nicht verfügbar"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Eingabemethode wechseln"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Flugmodus"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Zur Vorbereitung auf das Update ist eine PIN erforderlich"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Zur Vorbereitung auf das Update ist ein Muster erforderlich"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Zur Vorbereitung auf das Update ist ein Passwort erforderlich"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Nach dem Neustart des Geräts ist die Eingabe des Musters erforderlich"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Nach dem Neustart des Geräts ist die Eingabe der PIN erforderlich"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Nach dem Neustart des Geräts ist die Eingabe des Passworts erforderlich"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 1764284..8e4578f 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Καμία υπηρεσία."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Εναλλαγή μεθόδου εισαγωγής"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Λειτουργία πτήσης"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Απαιτείται PIN για την προετοιμασία για ενημέρωση"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Απαιτείται μοτίβο για την προετοιμασία για ενημέρωση"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Απαιτείται κωδικός πρόσβασης για την προετοιμασία για ενημέρωση"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Απαιτείται μοτίβο μετά από την επανεκκίνηση της συσκευής"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Απαιτείται PIN μετά από την επανεκκίνηση της συσκευής"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Απαιτείται κωδικός πρόσβασης μετά από την επανεκκίνηση της συσκευής"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 92a1594..21cfe48 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Aeroplane mode"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index 719f1a1..921ba6b 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Airplane mode"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 92a1594..21cfe48 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Aeroplane mode"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 92a1594..21cfe48 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"No service"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Aeroplane mode"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pattern required to prepare for update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password required to prepare for update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pattern required after device restarts"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN required after device restarts"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password required after device restarts"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index 975b1f6..fc59d0d 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎No service.‎‏‎‎‏‎"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎Switch input method‎‏‎‎‏‎"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎Airplane mode‎‏‎‎‏‎"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎PIN required to prepare for update‎‏‎‎‏‎"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎Pattern required to prepare for update‎‏‎‎‏‎"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎Password required to prepare for update‎‏‎‎‏‎"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎Pattern required after device restarts‎‏‎‎‏‎"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎PIN required after device restarts‎‏‎‎‏‎"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎Password required after device restarts‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 25ab615..ab0c8f3 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sin servicio"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de entrada"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modo de avión"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Se requiere el PIN para actualizar el sistema"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Se requiere el patrón para actualizar el sistema"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Se requiere la contraseña para actualizar el sistema"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Se requiere el patrón después de reiniciar el dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Se requiere el PIN después de reiniciar el dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Se requiere la contraseña después de reiniciar el dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index ce323c7..3813ddd 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sin servicio"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de introducción"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modo avión"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Debes introducir el PIN para prepararte para la actualización"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Debes dibujar el patrón para prepararte para la actualización"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Debes introducir la contraseña para prepararte para la actualización"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Debes introducir el patrón después de reiniciar el dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Debes introducir el PIN después de reiniciar el dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Debes introducir la contraseña después de reiniciar el dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 331a95c..f8ad18b 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Teenus puudub."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Vaheta sisestusmeetodit"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Lennukirežiim"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Värskendamiseks ettevalmistuste tegemiseks tuleb sisestada PIN-kood"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Värskendamiseks ettevalmistuste tegemiseks tuleb sisestada muster"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Värskendamiseks ettevalmistuste tegemiseks tuleb sisestada parool"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pärast seadme taaskäivitamist tuleb sisestada muster"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Pärast seadme taaskäivitamist tuleb sisestada PIN-kood"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pärast seadme taaskäivitamist tuleb sisestada parool"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 3ff224b..8510bee 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ez dago konektatuta inongo saretara."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Aldatu idazketa-metodoa"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Hegaldi modua"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN kodea behar da eguneratzea prestatzeko"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Eredua behar da eguneratzea prestatzeko"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Pasahitza behar da eguneratzea prestatzeko"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Eredua marraztu beharko duzu gailua berrabiarazten denean"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN kodea idatzi beharko duzu gailua berrabiarazten denean"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pasahitza idatzi beharko duzu gailua berrabiarazten denean"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 5e69636..43d3214 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"سرویسی وجود ندارد."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تغییر روش ورودی"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"حالت هواپیما"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"آماده‌سازی برای به‌روزرسانی به پین نیاز دارد"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"آماده‌سازی برای به‌روزرسانی به الگو نیاز دارد"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"آماده‌سازی برای به‌روزرسانی به گذرواژه نیاز دارد"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"بعد از بازنشانی دستگاه باید الگو وارد شود"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"بعد از بازنشانی دستگاه باید پین وارد شود"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"بعد از بازنشانی دستگاه باید گذرواژه وارد شود"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 54bc4d8..7dc12c9 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ei yhteyttä"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Vaihda syöttötapaa."</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Lentokonetila"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Päivitykseen valmistautuminen edellyttää PIN-koodia"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Päivitykseen valmistautuminen edellyttää kuviota"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Päivitykseen valmistautuminen edellyttää salasanaa"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Kuvio vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN-koodi vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Salasana vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 3e858c2..f093c17 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Aucun service"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Changer de méthode d\'entrée"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Mode Avion"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Le NIP est nécessaire pour préparer la mise à jour"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Le schéma est nécessaire pour préparer la mise à jour"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Le mot de passe est nécessaire pour préparer la mise à jour"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Le schéma est exigé après le redémarrage de l\'appareil"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Le NIP est exigé après le redémarrage de l\'appareil"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Le mot de passe est exigé après le redémarrage de l\'appareil"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index 8551fab..d6d5a32 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Aucun service."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Changer le mode de saisie"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Mode Avion"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Veuillez saisir le code pour lancer la préparation de la mise à jour"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Veuillez saisir le schéma pour lancer la préparation de la mise à jour"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Veuillez saisir le mot de passe pour lancer la préparation de la mise à jour"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Veuillez dessiner le schéma après le redémarrage de l\'appareil"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Veuillez saisir le code après le redémarrage de l\'appareil"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Veuillez saisir le mot de passe après le redémarrage de l\'appareil"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 420649e..5b8a255 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Non hai servizo."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambia o método de introdución"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modo avión"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Necesítase o PIN para preparar o dispositivo co fin de actualizalo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Necesítase o padrón para preparar o dispositivo co fin de actualizalo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Necesítase o contrasinal para preparar o dispositivo co fin de actualizalo"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"É necesario o padrón despois do reinicio do dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"É necesario o PIN despois do reinicio do dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"É necesario o contrasinal despois do reinicio do dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index b02d3d9..29e2fe0 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"કોઈ સેવા નથી."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ઇનપુટ પદ્ધતિ સ્વિચ કરો"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"એરપ્લેન મોડ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"અપડેટ માટે તૈયાર કરવા માટે પિન જરુરી છે"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"અપડેટ માટે તૈયાર કરવા માટે પૅટર્ન જરુરી છે"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"અપડેટ માટે તૈયાર કરવા માટે પાસવર્ડ જરુરી છે"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પૅટર્ન જરૂરી છે"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પિન જરૂરી છે"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ઉપકરણનો પુનઃપ્રારંભ થાય તે પછી પાસવર્ડ જરૂરી છે"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index f6b15de..d26c79f 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"कोई सेवा नहीं."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट का तरीका बदलें"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"हवाई जहाज़ मोड"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"अपडेट के लिए पिन डालना ज़रूरी है"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"अपडेट के लिए पैटर्न डालना ज़रूरी है"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"अपडेट के लिए पासवर्ड डालना ज़रूरी है"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"डिवाइस फिर से चालू होने के बाद पैटर्न ज़रूरी है"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"डिवाइस फिर से चालू होने के बाद पिन ज़रूरी है"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"डिवाइस फिर से चालू होने के बाद पासवर्ड ज़रूरी है"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 49db3f88..c8dd9b0 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -104,6 +104,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nema usluge."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promjena načina unosa"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Način rada u zrakoplovu"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Za pripremu ažuriranja potreban je PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Za pripremu ažuriranja potreban je uzorak"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Za pripremu ažuriranja potrebna je zaporka"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Nakon ponovnog pokretanja uređaja morate unijeti uzorak"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Nakon ponovnog pokretanja uređaja morate unijeti PIN"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Nakon ponovnog pokretanja uređaja morate unijeti zaporku"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index c26998f..f0023d2 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nincs szolgáltatás."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Beviteli módszer váltása"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Repülős üzemmód"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"A frissítésre való felkészüléshez meg kell adni a PIN-kódot"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"A frissítésre való felkészüléshez meg kell adni a mintát"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"A frissítésre való felkészüléshez meg kell adni a jelszót"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Az eszköz újraindítását követően meg kell adni a mintát"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Az eszköz újraindítását követően meg kell adni a PIN-kódot"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Az eszköz újraindítását követően meg kell adni a jelszót"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index ad949d4..4224705 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ծառայությունն անհասանելի է։"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Փոխել ներածման եղանակը"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Ավիառեժիմ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Թարմացմանը պատրաստվելու համար անհրաժեշտ է մուտքագրել PIN-ը"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Թարմացմանը պատրաստվելու համար անհրաժեշտ է մուտքագրել նախշը"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Թարմացմանը պատրաստվելու համար անհրաժեշտ է մուտքագրել գաղտնաբառը"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել նախշը"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել PIN կոդը"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Սարքը վերագործարկելուց հետո անհրաժեշտ է մուտքագրել գաղտնաբառը"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 875d8d5..9c00ff7 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Tidak ada layanan."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Beralih metode masukan"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Mode pesawat"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN diwajibkan untuk menyiapkan update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pola diwajibkan untuk menyiapkan update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Sandi diwajibkan untuk menyiapkan update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pola diperlukan setelah perangkat dimulai ulang"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN diperlukan setelah perangkat dimulai ulang"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Sandi diperlukan setelah perangkat dimulai ulang"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index e40cdca..5e37655 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ekkert símasamband."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Skipta um innsláttaraðferð"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Flugstilling"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Slá þarf inn PIN-númer til að undirbúa uppfærsluna"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Teikna þarf mynstur til að undirbúa uppfærsluna"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Gefa þarf upp aðgangsorð til að undirbúa uppfærsluna"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Mynsturs er krafist þegar tækið er endurræst"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN-númers er krafist þegar tækið er endurræst"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Aðgangsorðs er krafist þegar tækið er endurræst"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 16767d1..80deb34 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nessun servizio."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambia metodo di immissione"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modalità aereo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN obbligatorio per la preparazione all\'aggiornamento"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Sequenza obbligatoria per la preparazione all\'aggiornamento"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Password obbligatoria per la preparazione all\'aggiornamento"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Sequenza obbligatoria dopo il riavvio del dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN obbligatorio dopo il riavvio del dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Password obbligatoria dopo il riavvio del dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index e054f62..71f3048 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"אין שירות."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"החלפת שיטת קלט"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"מצב טיסה"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"נדרש קוד אימות להכנת העדכון"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"נדרש קו ביטול נעילה להכנת העדכון"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"נדרשת סיסמה להכנת העדכון"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"יש להזין את קו ביטול הנעילה לאחר הפעלה מחדש של המכשיר"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"יש להזין קוד גישה לאחר הפעלה מחדש של המכשיר"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"יש להזין סיסמה לאחר הפעלה מחדש של המכשיר"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 957d78a..23ff82c 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"通信サービスはありません。"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"入力方法の切り替え"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"機内モード"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"更新の準備には PIN の入力が必要です"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"更新の準備にはパターンの入力が必要です"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"更新の準備にはパスワードが必要です"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"デバイスの再起動後はパターンの入力が必要となります"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"デバイスの再起動後は PIN の入力が必要となります"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"デバイスの再起動後はパスワードの入力が必要となります"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index d0d15fe..25b9b1b 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"სერვისი არ არის."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"შეყვანის მეთოდის გადართვა"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"თვითმფრინავის რეჟიმი"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"განახლების მოსამზადებლად საჭიროა PIN-კოდი"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"განახლების მოსამზადებლად საჭიროა ნიმუში"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"განახლების მოსამზადებლად საჭიროა პაროლი"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"მოწყობილობის გადატვირთვის შემდეგ საჭიროა ნიმუშის დახატვა"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"მოწყობილობის გადატვირთვის შემდეგ საჭიროა PIN-კოდის შეყვანა"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"მოწყობილობის გადატვირთვის შემდეგ საჭიროა პაროლის შეყვანა"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 96972a7..4989e91 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Қызмет көрсетілмейді."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Енгізу әдісін ауыстыру"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Ұшақ режимі"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Жаңа нұсқа орнатуға дайындау үшін PIN кодын енгізу қажет."</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Жаңа нұсқа орнатуға дайындау үшін өрнек енгізу қажет."</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Жаңа нұсқа орнатуға дайындау үшін құпия сөз енгізу қажет."</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Құрылғы қайта іске қосылғаннан кейін, өрнекті енгізу қажет"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Құрылғы қайта іске қосылғаннан кейін, PIN кодын енгізу қажет"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Құрылғы қайта іске қосылғаннан кейін, құпия сөзді енгізу қажет"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 24b5c23..e5ea9ea 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"គ្មាន​សេវា​ទេ។"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ប្ដូរ​វិធី​បញ្ចូល"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"មុខងារ​ពេល​ជិះ​យន្តហោះ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"តម្រូវ​ឱ្យ​មាន​កូដ PIN ដើម្បី​រៀបចំ​ធ្វើបច្ចុប្បន្នភាព"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"តម្រូវ​ឱ្យ​មាន​លំនាំ ដើម្បី​រៀបចំ​ធ្វើបច្ចុប្បន្នភាព"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"តម្រូវ​ឱ្យ​មាន​ពាក្យ​សម្ងាត់ ដើម្បី​រៀបចំ​ធ្វើបច្ចុប្បន្នភាព"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"តម្រូវឲ្យប្រើលំនាំ បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"តម្រូវឲ្យបញ្ចូលកូដ PIN បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"តម្រូវឲ្យបញ្ចូលពាក្យសម្ងាត់ បន្ទាប់ពីឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 785ca43..8173ca0 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"ಸೇವೆ ಇಲ್ಲ."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ಇನ್‌ಪುಟ್‌‌ ವಿಧಾನ ಬದಲಿಸಿ"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಸಿದ್ಧಗೊಳಿಸಲು, ಪಿನ್‌‌ ಅಗತ್ಯವಿದೆ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಸಿದ್ಧಗೊಳಿಸಲು, ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿದೆ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಸಿದ್ಧಗೊಳಿಸಲು, ಪಾಸ್‌ವರ್ಡ್ ಅಗತ್ಯವಿದೆ"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ಸಾಧನ ಮರುಪ್ರಾರಂಭಗೊಂಡ ನಂತರ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ಸಾಧನ ಮರುಪ್ರಾರಂಭಗೊಂಡ ನಂತರ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ಸಾಧನ ಮರುಪ್ರಾರಂಭಗೊಂಡ ನಂತರ ಪಾಸ್‌ವರ್ಡ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 6ae5935..06074b2 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"서비스 불가"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"입력 방법 전환"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"비행기 모드"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"업데이트를 준비하려면 PIN이 필요합니다."</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"업데이트를 준비하려면 패턴이 필요합니다."</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"업데이트를 준비하려면 비밀번호가 필요합니다."</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"기기가 다시 시작되면 패턴이 필요합니다."</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"기기가 다시 시작되면 PIN이 필요합니다."</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"기기가 다시 시작되면 비밀번호가 필요합니다."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 9675cc9..022726e 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Байланыш жок."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Киргизүү ыкмасын өзгөртүү"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Учак режими"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Жаңыртууга даярдоо үчүн PIN код талап кылынат"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Жаңыртууга даярдоо үчүн графикалык ачкыч талап кылынат"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Жаңыртууга даярдоо үчүн сырсөз талап кылынат"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкычты тартуу талап кылынат"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Түзмөк кайра күйгүзүлгөндөн кийин PIN-кодду киргизүү талап кылынат"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Түзмөк кайра күйгүзүлгөндөн кийин сырсөздү киргизүү талап кылынат"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index ebaffb1..25e36c1 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"ບໍ່ມີບໍລິການ"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ໂໝດໃນຍົນ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ຕ້ອງໃຊ້ PIN ເພື່ອກະກຽມອັບເດດ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ຕ້ອງໃຊ້ຮູບແບບເພື່ອກະກຽມອັບເດດ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ຕ້ອງໃຊ້ລະຫັດຜ່ານເພື່ອກະກຽມອັບເດດ"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ຈຳເປັນຕ້ອງມີແບບຮູບປົດລັອກຫຼັງຈາກອຸປະກອນເລີ່ມລະບົບໃໝ່"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ຈຳເປັນຕ້ອງມີ PIN ຫຼັງຈາກອຸປະກອນເລີ່ມລະບົບໃໝ່"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານຫຼັງຈາກອຸປະກອນເລີ່ມລະບົບໃໝ່"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 4d598f6..158efe2 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nėra paslaugos."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Perjungti įvesties metodą"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Lėktuvo režimas"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Kad būtų pasiruošta atnaujinti, reikia įvesti PIN kodą"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Kad būtų pasiruošta atnaujinti, reikia įvesti atrakinimo piešinį"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kad būtų pasiruošta atnaujinti, reikia įvesti slaptažodį"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Iš naujo paleidus įrenginį būtinas atrakinimo piešinys"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Iš naujo paleidus įrenginį būtinas PIN kodas"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Iš naujo paleidus įrenginį būtinas slaptažodis"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index fad67d5..c4a4e7f 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -104,6 +104,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nav pakalpojuma."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Pārslēgt ievades metodi"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Lidojuma režīms"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Lai sagatavotos atjauninājumam, nepieciešams PIN."</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Lai sagatavotos atjauninājumam, nepieciešama kombinācija."</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Lai sagatavotos atjauninājumam, nepieciešama parole."</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Pēc ierīces restartēšanas ir jāievada atbloķēšanas kombinācija."</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Pēc ierīces restartēšanas ir jāievada PIN kods."</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pēc ierīces restartēšanas ir jāievada parole."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 1397f46..de4a83b 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Нема услуга."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Префрли метод за внесување"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Авионски режим"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Потребен е PIN за да се подготви за ажурирање"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Потребна е шема за да се подготви за ажурирање"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Потребна е лозинка за да се подготви за ажурирање"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Потребна е шема по рестартирање на уредот"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Потребен е PIN-код по рестартирање на уредот"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Потребна е лозинка по рестартирање на уредот"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index f82f822..da26ba7 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"സേവനമില്ല"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ഇൻപുട്ട് രീതി മാറുക"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ഫ്ലൈറ്റ് മോഡ്"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"അപ്‌ഡേറ്റിനായി തയ്യാറെടുക്കാൻ പിൻ ആവശ്യമാണ്"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"അപ്‌ഡേറ്റിനായി തയ്യാറെടുക്കാൻ പാറ്റേൺ ആവശ്യമാണ്"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"അപ്‌ഡേറ്റിനായി തയ്യാറെടുക്കാൻ പാസ്‌വേഡ് ആവശ്യമാണ്"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ഉപകരണം റീസ്റ്റാർട്ടായശേഷം ‌പാറ്റേൺ വരയ്‌ക്കേണ്ടതുണ്ട്"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ഉപകരണം റീസ്റ്റാർട്ടായശേഷം ‌പിൻ നൽകേണ്ടതുണ്ട്"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ഉപകരണം റീസ്റ്റാർട്ടായശേഷം ‌പാസ്‌വേഡ് നൽകേണ്ടതുണ്ട്"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 462017a..fb032f1 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Үйлчилгээ алга."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Оруулах аргыг сэлгэх"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Нислэгийн горим"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Шинэчлэхэд бэлтгэхийн тулд ПИН шаардлагатай"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Шинэчлэхэд бэлтгэхийн тулд хээ шаардлагатай"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Шинэчлэхэд бэлтгэхийн тулд нууц үг шаардлагатай"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Төхөөрөмжийг дахин эхлүүлсний дараа загвар оруулах шаардлагатай"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Төхөөрөмжийг дахин эхлүүлсний дараа ПИН оруулах шаардлагатай"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Төхөөрөмжийг дахин эхлүүлсний дараа нууц үг оруулах шаардлагатай"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 0166791..e79e5c5 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"सेवा नाही."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट पद्धत स्विच करा"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"विमान मोड"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"अपडेटसाठी तयार करण्याकरिता पिन आवश्यक आहे"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"अपडेटसाठी तयार करण्याकरिता पॅटर्न आवश्यक आहे"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"अपडेटसाठी तयार करण्याकरिता पासवर्ड आवश्यक आहे"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"डिव्हाइस रीस्टार्ट झाल्यावर पॅटर्न आवश्यक आहे"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"डिव्हाइस रीस्टार्ट झाल्यावर पिन आवश्यक आहे"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"डिव्हाइस रीस्टार्ट झाल्यावर पासवर्ड आवश्यक आहे"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 6750086..5bc5df4 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Tiada perkhidmatan."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Tukar kaedah masukan"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Mod Pesawat"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN diperlukan untuk menyediakan kemas kini"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Corak diperlukan untuk menyediakan kemas kini"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kata laluan diperlukan untuk menyediakan kemas kini"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Corak diperlukan setelah peranti dimulakan semula"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN diperlukan setelah peranti dimulakan semula"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Kata laluan diperlukan setelah peranti dimulakan semula"</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index 3b32f06..43732d8 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"ဝန်ဆောင်မှု မရှိပါ။"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"စာရိုက်စနစ်ပြောင်းရန်"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"လေယာဉ်ပျံမုဒ်"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"အပ်ဒိတ်အတွက် ပြင်ဆင်ရန် ပင်နံပါတ် လိုပါသည်"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"အပ်ဒိတ်အတွက် ပြင်ဆင်ရန် ပုံစံလိုပါသည်"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"အပ်ဒိတ်အတွက် ပြင်ဆင်ရန် စကားဝှက် လိုပါသည်"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"စက်ပစ္စည်းကို ပိတ်ပြီးပြန်ဖွင့်လိုက်သည့်အခါတွင် ပုံစံ လိုအပ်ပါသည်"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"စက်ပစ္စည်းကို ပိတ်ပြီးပြန်ဖွင့်လိုက်သည့်အခါတွင် ပင်နံပါတ် လိုအပ်ပါသည်"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"စက်ပစ္စည်းကို ပိတ်ပြီးပြန်ဖွင့်လိုက်သည့်အခါတွင် စကားဝှက် လိုအပ်ပါသည်"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index ebd8f29..6dd3b2a 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen tilkobling."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Bytt inndatametode"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Flymodus"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN-koden kreves for å klargjøre for oppdateringen"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Mønsteret kreves for å klargjøre for oppdateringen"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Passordet kreves for å klargjøre for oppdateringen"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du må tegne mønsteret etter at enheten har startet på nytt"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Du må skrive inn PIN-koden etter at enheten har startet på nytt"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Du må skrive inn passordet etter at enheten har startet på nytt"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 0cec32e..37b2a60 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"सेवा उपलब्ध छैन।"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट विधिलाई स्विच गर्नुहोस्"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"हवाइजहाज मोड"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"अद्यावधिक गर्ने कार्यका लागि तयार पार्न PIN चाहिन्छ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"अद्यावधिक गर्ने कार्यका लागि तयार पार्न प्याटर्न चाहिन्छ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"अद्यावधिक गर्ने कार्यका लागि तयार पार्न पासवर्ड चाहिन्छ"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"यन्त्र पुनः सुरु भएपछि ढाँचा आवश्यक पर्दछ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"यन्त्र पुनः सुरु भएपछि PIN आवश्यक पर्दछ"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"यन्त्र पुनः सुरु भएपछि पासवर्ड आवश्यक पर्दछ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index aa783e8..f3c35a4 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Geen service."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Invoermethode wijzigen"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Vliegtuigmodus"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Pincode vereist voor voorbereiding op update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Patroon vereist voor voorbereiding op update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Wachtwoord vereist voor voorbereiding op update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Patroon vereist nadat het apparaat opnieuw is opgestart"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Pincode vereist nadat het apparaat opnieuw is opgestart"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Wachtwoord vereist nadat het apparaat opnieuw is opgestart"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index 8bbdcf1..e92dc42 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"କୌଣସି ସେବା ନାହିଁ।"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ଇନପୁଟ୍‌ ପଦ୍ଧତି ବଦଳାନ୍ତୁ"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ଅପଡେଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ ହେବାକୁ PIN ଆବଶ୍ୟକ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ଅପଡେଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ ହେବାକୁ ପାଟର୍ନ ଆବଶ୍ୟକ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ଅପଡେଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ ହେବାକୁ ପାସୱାର୍ଡ ଆବଶ୍ୟକ"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ଡିଭାଇସ୍‍ ରିଷ୍ଟାର୍ଟ ହେବା ପରେ ପାଟର୍ନ ଆବଶ୍ୟକ ଅଟେ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ଡିଭାଇସ୍‍ ରିଷ୍ଟାର୍ଟ ହେବାପରେ ପାସ୍‌ୱର୍ଡ ଆବଶ୍ୟକ"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ଡିଭାଇସ୍‍ ରିଷ୍ଟାର୍ଟ ହେବା ପରେ ପାସୱର୍ଡ ଆବଶ୍ୟକ ଅଟେ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 78e0665..5c83ab8 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"ਕੋਈ ਸੇਵਾ ਨਹੀਂ।"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ਇਨਪੁੱਟ ਵਿਧੀ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ਅੱਪਡੇਟ ਨੂੰ ਤਿਆਰ ਕਰਨ ਲਈ ਪਿੰਨ ਲੋੜੀਂਦਾ ਹੈ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ਅੱਪਡੇਟ ਨੂੰ ਤਿਆਰ ਕਰਨ ਲਈ ਪੈਟਰਨ ਲੋੜੀਂਦਾ ਹੈ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ਅੱਪਡੇਟ ਨੂੰ ਤਿਆਰ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਲੋੜੀਂਦਾ ਹੈ"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪੈਟਰਨ ਦੀ ਲੋੜ ਹੈ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪਿੰਨ ਦੀ ਲੋੜ ਹੈ"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ \'ਤੇ ਪਾਸਵਰਡ ਦੀ ਲੋੜ ਹੈ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 9b6f857..34633d3 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Brak usługi."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Przełączanie metody wprowadzania"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Tryb samolotowy"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Aby przygotować się do aktualizacji, wymagany jest kod PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Aby przygotować się do aktualizacji, wymagany jest wzór"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Aby przygotować się do aktualizacji, wymagane jest hasło"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po ponownym uruchomieniu urządzenia wymagany jest wzór"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po ponownym uruchomieniu urządzenia wymagany jest kod PIN"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po ponownym uruchomieniu urządzenia wymagane jest hasło"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index cc0c044..a770297 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sem serviço."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alterar o método de entrada"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modo avião"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Insira o PIN para se preparar para a atualização"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Insira o padrão para se preparar para a atualização"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Insira a senha para se preparar para a atualização"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"O padrão é exigido após a reinicialização do dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"O PIN é exigido após a reinicialização do dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"A senha é exigida após a reinicialização do dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 5af8bc0..09cfcf1 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sem serviço."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alternar o método de introdução"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modo de avião"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"É necessário introduzir o PIN para a preparação para a atualização."</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"É necessário introduzir o padrão para a preparação para a atualização."</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"É necessário introduzir a palavra-passe para a preparação para a atualização."</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"É necessário um padrão após reiniciar o dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"É necessário um PIN após reiniciar o dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"É necessária uma palavra-passe após reiniciar o dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index cc0c044..a770297 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Sem serviço."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alterar o método de entrada"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modo avião"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Insira o PIN para se preparar para a atualização"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Insira o padrão para se preparar para a atualização"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Insira a senha para se preparar para a atualização"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"O padrão é exigido após a reinicialização do dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"O PIN é exigido após a reinicialização do dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"A senha é exigida após a reinicialização do dispositivo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 8122241..7df2db6 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -104,6 +104,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Fără serviciu."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Comutați metoda de introducere"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Mod Avion"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Pentru a vă pregăti pentru actualizare este necesar codul PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Pentru a vă pregăti pentru actualizare este necesar modelul"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Pentru a vă pregăti pentru actualizare este necesară parola"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Modelul este necesar după repornirea dispozitivului"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Codul PIN este necesar după repornirea dispozitivului"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Parola este necesară după repornirea dispozitivului"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index b80b479..ccd3c96 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Нет сигнала."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Сменить способ ввода"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Режим полета"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Для подготовки к обновлению необходимо ввести PIN-код."</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Для подготовки к обновлению необходимо ввести графический ключ."</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Для подготовки к обновлению необходимо ввести пароль."</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"После перезагрузки устройства необходимо ввести графический ключ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"После перезагрузки устройства необходимо ввести PIN-код"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"После перезагрузки устройства необходимо ввести пароль"</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 1cd876f..3dfc282 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"සේවාව නැත."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ආදාන ක්‍රමය මාරු කිරීම"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ගුවන් යානා ප්‍රකාරය"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"යාවත්කාලීනය සඳහා සුදානම් කිරීමට PIN අවශ්‍යය"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"යාවත්කාලීනය සඳහා සුදානම් කිරීමට රටාව අවශ්‍යය"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"යාවත්කාලීනය සඳහා සුදානම් කිරීමට මුරපදය අවශ්‍යය"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"උපාංගය නැවත ආරම්භ වූ පසු රටාව අවශ්‍යයි"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"උපාංගය නැවත ආරම්භ වූ පසු PIN අංකය අවශ්‍යයි"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"උපාංගය නැවත ආරම්භ වූ පසු මුරපදය අවශ්‍යයි"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index 801a7db..8568e14 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Žiadny signál."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Prepnúť metódu vstupu"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Režim v lietadle"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Príprava na aktualizáciu vyžaduje zadanie kódu PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Príprava na aktualizáciu vyžaduje zadanie vzoru"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Príprava na aktualizáciu vyžaduje zadanie hesla"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po reštartovaní zariadenia musíte zadať bezpečnostný vzor"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po reštartovaní zariadenia musíte zadať kód PIN"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po reštartovaní zariadenia musíte zadať heslo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index a141ed7..16dc4a8 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ni storitve."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Preklop načina vnosa"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Način za letalo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Za pripravo na posodobitev morate vnesti kodo PIN"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Za pripravo na posodobitev morate vnesti vzorec"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Za pripravo na posodobitev morate vnesti geslo"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Po vnovičnem zagonu naprave je treba vnesti vzorec"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Po vnovičnem zagonu naprave je treba vnesti kodo PIN"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Po vnovičnem zagonu naprave je treba vnesti geslo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 1d34e3f..ec44b61 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Nuk ka shërbim."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Ndërro metodën e hyrjes"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Modaliteti i aeroplanit"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Kërkohet kodi PIN për t\'u përgatitur për përditësimin"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Kërkohet motivi për t\'u përgatitur për përditësimin"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kërkohet fjalëkalimi për t\'u përgatitur për përditësimin"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Kërkohet motivi pas rinisjes së pajisjes"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Kërkohet kodi PIN pas rinisjes së pajisjes"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Kërkohet fjalëkalimi pas rinisjes së pajisjes"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index f83df3f..24a1125 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -104,6 +104,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Мрежа није доступна."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Промени метод уноса"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Режим рада у авиону"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"PIN је обавезан ради припреме за ажурирање"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Шаблон је обавезан ради припреме за ажурирање"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Лозинка је обавезна ради припреме за ажурирање"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Треба да унесете шаблон када се уређај поново покрене"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Треба да унесете PIN када се уређај поново покрене"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Треба да унесете лозинку када се уређај поново покрене"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index a037bff..a37c480 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen tjänst."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Byt inmatningsmetod"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Flygplansläge"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Pinkod krävs för att förbereda för uppdatering"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Grafiskt lösenord krävs för att förbereda för uppdatering"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Lösenord krävs för att förbereda för uppdatering"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du måste ange grafiskt lösenord när du har startat om enheten"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Du måste ange pinkod när du har startat om enheten"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Du måste ange lösenord när du har startat om enheten"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index efa5ecf..c4a9a14 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Hakuna mtandao."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Kubadili mbinu ya kuingiza data"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Hali ya ndegeni"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Inahitaji PIN ili kujiandaa kwa ajili ya sasisho"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Inahitaji mchoro ili kujiandaa kwa ajili ya sasisho"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Inahitaji nenosiri ili kujiandaa kwa ajili ya sasisho"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Unafaa kuchora mchoro baada ya kuwasha kifaa upya"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Unafaa kuweka PIN baada ya kuwasha kifaa upya"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Unafaa kuweka nenosiri baada ya kuwasha kifaa upya"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 96dbbb0..a4dc0be 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"சேவை இல்லை."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"உள்ளீட்டு முறையை மாற்றும்"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"விமானப் பயன்முறை"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"புதுப்பிப்பிற்குத் தயார்செய்ய பின் தேவை"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"புதுப்பிப்பிற்குத் தயார்செய்ய பேட்டர்ன் தேவை"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"புதுப்பிப்பிற்குத் தயார்செய்ய கடவுச்சொல் தேவை"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"சாதனத்தை மீண்டும் தொடங்கியதும், பேட்டர்னை வரைய வேண்டும்"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"சாதனத்தை மீண்டும் தொடங்கியதும், பின்னை உள்ளிட வேண்டும்"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"சாதனத்தை மீண்டும் தொடங்கியதும், கடவுச்சொல்லை உள்ளிட வேண்டும்"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 74386bc..3e27ce8 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"సేవ లేదు."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ఇన్‌పుట్ పద్ధతిని మార్చు"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"విమానం మోడ్"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"అప్‌డేట్‌కు సిద్ధం చేయడానికి పిన్ అవసరం"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"అప్‌డేట్‌కు సిద్ధం చేయడానికి ఆకృతి అవసరం"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"అప్‌డేట్‌కు సిద్ధం చేయడానికి పాస్‌వర్డ్ అవసరం"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత నమూనాను గీయాలి"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"డివైజ్‌ను పునఃప్రారంభించిన తర్వాత పిన్ నమోదు చేయాలి"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"పరికరాన్ని పునఃప్రారంభించిన తర్వాత పాస్‌వర్డ్‌ను నమోదు చేయాలి"</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index aa9e693..8f94c636 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"ไม่มีบริการ"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"สลับวิธีการป้อนข้อมูล"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"โหมดบนเครื่องบิน"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"ต้องใช้ PIN เพื่อเตรียมรับการอัปเดต"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"ต้องใช้รูปแบบเพื่อเตรียมรับการอัปเดต"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"ต้องใช้รหัสผ่านเพื่อเตรียมรับการอัปเดต"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"ต้องวาดรูปแบบหลังจากอุปกรณ์รีสตาร์ท"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"ต้องระบุ PIN หลังจากอุปกรณ์รีสตาร์ท"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"ต้องป้อนรหัสผ่านหลังจากอุปกรณ์รีสตาร์ท"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 7b7e17d..bd87b20 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Walang serbisyo."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Magpalit ng pamamaraan ng pag-input"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Airplane mode"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Kinakailangan ang PIN para makapaghanda sa pag-update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Kinakailangan ang pattern para makapaghanda sa pag-update"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Kinakailangan ang password para makapaghanda sa pag-update"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Kailangan ng pattern pagkatapos mag-restart ng device"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Kailangan ng PIN pagkatapos mag-restart ng device"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Kailangan ng password pagkatapos mag-restart ng device"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index 8c0caea..cf37451 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Hizmet yok."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Giriş yöntemini değiştir"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Uçak modu"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Güncellemenin hazırlanması için PIN gerekli"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Güncellemenin hazırlanması için desen gerekli"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Güncellemenin hazırlanması için şifre gerekli"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Cihaz yeniden başladıktan sonra desen gerekir"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Cihaz yeniden başladıktan sonra PIN gerekir"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Cihaz yeniden başladıktan sonra şifre gerekir"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 6e5ce0f..0ccd012 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -107,6 +107,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Зв’язку немає."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Змінити метод введення"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Режим польоту"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Щоб підготуватися до оновлення, введіть PIN-код"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Щоб підготуватися до оновлення, введіть ключ"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Щоб підготуватися до оновлення, введіть пароль"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Після перезавантаження пристрою потрібно ввести ключ"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Після перезавантаження пристрою потрібно ввести PIN-код"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Після перезавантаження пристрою потрібно ввести пароль"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 7b946aa..981bc033 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"کوئی سروس نہیں ہے۔"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"اندراج کا طریقہ سوئچ کریں"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"ہوائی جہاز وضع"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"‏اپ ڈیٹ تیار کرنے کے لیے PIN درکار ہے"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"اپ ڈیٹ تیار کرنے کے لیے پیٹرن درکار ہے"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"اپ ڈیٹ تیار کرنے کے لیے پاس ورڈ درکار ہے"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"آلہ دوبارہ چالو ہونے کے بعد پیٹرن درکار ہوتا ہے"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"‏آلہ دوبارہ چالو ہونے کے بعد PIN درکار ہوتا ہے"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"آلہ دوبارہ چالو ہونے کے بعد پاسورڈ درکار ہوتا ہے"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index a6c2aa0..1905e64e 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Aloqa yo‘q."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Matn kiritish usulini almashtirish"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Parvoz rejimi"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Yangilashga tayyorlash uchun PIN kod talab etiladi"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Yangilashga tayyorlash uchun grafik kalit talab etiladi"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Yangilashga tayyorlash uchun parol talab etiladi"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Qurilma o‘chirib yoqilgandan keyin grafik kalit talab qilinadi"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Qurilma o‘chirib yoqilgandan keyin PIN kod talab qilinadi"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Qurilma o‘chirib yoqilgandan keyin parol talab qilinadi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 31737fc..cfb1564 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Không có dịch vụ."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Chuyển phương thức nhập"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Chế độ trên máy bay"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Cần nhập mã PIN để chuẩn bị cập nhật"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Cần nhập hình mở khóa để chuẩn bị cập nhật"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Cần nhập mật khẩu để chuẩn bị cập nhật"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Yêu cầu hình mở khóa sau khi thiết bị khởi động lại"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Yêu cầu mã PIN sau khi thiết bị khởi động lại"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Yêu cầu mật khẩu sau khi thiết bị khởi động lại"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index b4bff5f..be162b0 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"无服务。"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"切换输入法"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"飞行模式"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"需要输入 PIN 码才能让设备做好更新准备"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"需要绘制解锁图案才能让设备做好更新准备"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"需要输入密码才能让设备做好更新准备"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"重启设备后需要绘制解锁图案"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"重启设备后需要输入 PIN 码"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"重启设备后需要输入密码"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index b3d3877..33e5b44 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"沒有服務。"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"轉換輸入方法"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"飛行模式"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"必須提供 PIN 碼,才能準備進行更新"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"必須畫出上鎖圖案,才能準備進行更新"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"必須輸入密碼,才能準備進行更新"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"裝置重新啟動後,必須畫出上鎖圖案才能使用"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"裝置重新啟動後,必須輸入 PIN 碼才能使用"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"裝置重新啟動後,必須輸入密碼才能使用"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 03dec48..763233c 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"沒有服務。"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"切換輸入法"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"飛航模式"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"請輸入 PIN 碼,以便為更新作業進行準備"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"請畫出解鎖圖案,以便為更新作業進行準備"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"請輸入密碼,以便為更新作業進行準備"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"裝置重新啟動後需要畫出解鎖圖案"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"裝置重新啟動後需要輸入 PIN 碼"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"裝置重新啟動後需要輸入密碼"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index 5ab567f..397c868 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -101,6 +101,9 @@
     <string name="keyguard_carrier_default" msgid="6359808469637388586">"Ayikho isevisi"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Shintsha indlela yokufaka"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Imodi yendiza"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pin" msgid="8878724145347297575">"Iphinikhodi iyadingeka ukuze kulungiselelwe isibuyekezo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_pattern" msgid="4873394344883271519">"Iphethini iyadingeka ukuze kulungiselelwe isibuyekezo"</string>
+    <string name="kg_prompt_reason_prepare_for_update_password" msgid="5625446803865598337">"Iphasiwedi iyadingeka ukuze kulungiselelwe isibuyekezo"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Iphethini iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Iphinikhodi iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string>
     <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Iphasiwedi iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string>
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
new file mode 100644
index 0000000..dc070cb
--- /dev/null
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<!-- This is the notification shade window. -->
+<com.android.systemui.statusbar.phone.NotificationShadeWindowView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true">
+
+    <com.android.systemui.statusbar.BackDropView
+            android:id="@+id/backdrop"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone"
+            sysui:ignoreRightInset="true"
+            >
+        <ImageView android:id="@+id/backdrop_back"
+                   android:layout_width="match_parent"
+                   android:scaleType="centerCrop"
+                   android:layout_height="match_parent" />
+        <ImageView android:id="@+id/backdrop_front"
+                   android:layout_width="match_parent"
+                   android:layout_height="match_parent"
+                   android:scaleType="centerCrop"
+                   android:visibility="invisible" />
+    </com.android.systemui.statusbar.BackDropView>
+
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_for_bubble"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+        />
+
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_behind"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+        />
+
+    <include layout="@layout/status_bar_expanded"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible" />
+
+    <include layout="@layout/brightness_mirror" />
+
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_in_front"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+    />
+
+    <LinearLayout
+        android:id="@+id/lock_icon_container"
+        android:orientation="vertical"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/status_bar_height"
+        android:layout_gravity="top|center_horizontal">
+        <com.android.systemui.statusbar.phone.LockIcon
+            android:id="@+id/lock_icon"
+            android:layout_width="@dimen/keyguard_lock_width"
+            android:layout_height="@dimen/keyguard_lock_height"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="@dimen/keyguard_lock_padding"
+            android:contentDescription="@string/accessibility_unlock_button"
+            android:src="@*android:drawable/ic_lock"
+            android:scaleType="center" />
+        <com.android.keyguard.KeyguardMessageArea
+            android:id="@+id/keyguard_message_area"
+            style="@style/Keyguard.TextView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/keyguard_lock_padding"
+            android:gravity="center"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:focusable="true" />
+    </LinearLayout>
+</com.android.systemui.statusbar.phone.NotificationShadeWindowView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 9716a00..8fee2cf9 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2012, The Android Open Source Project
+** 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.
@@ -17,7 +17,7 @@
 */
 -->
 
-<!-- This is the combined status bar / notification panel window. -->
+<!-- This is the status bar window. -->
 <com.android.systemui.statusbar.phone.StatusBarWindowView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
@@ -25,85 +25,8 @@
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">
 
-    <com.android.systemui.statusbar.BackDropView
-            android:id="@+id/backdrop"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:visibility="gone"
-            sysui:ignoreRightInset="true"
-            >
-        <ImageView android:id="@+id/backdrop_back"
-                   android:layout_width="match_parent"
-                   android:scaleType="centerCrop"
-                   android:layout_height="match_parent" />
-        <ImageView android:id="@+id/backdrop_front"
-                   android:layout_width="match_parent"
-                   android:layout_height="match_parent"
-                   android:scaleType="centerCrop"
-                   android:visibility="invisible" />
-    </com.android.systemui.statusbar.BackDropView>
-
-    <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_for_bubble"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        sysui:ignoreRightInset="true"
-        />
-
     <FrameLayout
         android:id="@+id/status_bar_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
-
-    <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_behind"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        sysui:ignoreRightInset="true"
-        />
-
-    <include layout="@layout/status_bar_expanded"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="invisible" />
-
-    <include layout="@layout/brightness_mirror" />
-
-    <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_in_front"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:importantForAccessibility="no"
-        sysui:ignoreRightInset="true"
-    />
-
-    <LinearLayout
-        android:id="@+id/lock_icon_container"
-        android:orientation="vertical"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/status_bar_height"
-        android:layout_gravity="top|center_horizontal">
-        <com.android.systemui.statusbar.phone.LockIcon
-            android:id="@+id/lock_icon"
-            android:layout_width="@dimen/keyguard_lock_width"
-            android:layout_height="@dimen/keyguard_lock_height"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginTop="@dimen/keyguard_lock_padding"
-            android:contentDescription="@string/accessibility_unlock_button"
-            android:src="@*android:drawable/ic_lock"
-            android:scaleType="center" />
-        <com.android.keyguard.KeyguardMessageArea
-            android:id="@+id/keyguard_message_area"
-            style="@style/Keyguard.TextView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/keyguard_lock_padding"
-            android:gravity="center"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:focusable="true" />
-    </LinearLayout>
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index ea7b9bb..4de8543 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is gedeaktiveer"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is geaktiveer"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swiep op om programme te wissel"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Sleep regs om programme vinnig te wissel"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Wissel oorsig"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Vee alles uit"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Bestuur"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Stil kennisgewings"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekke"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vee alle stil kennisgewings uit"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kennisgewings onderbreek deur Moenie Steur Nie"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Pasmaak"</string>
     <string name="notification_done" msgid="6215117625922713976">"Klaar"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Ontdoen"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kennisgewingkontroles"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"kennisgewing-sluimeropsies"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9412f0f..87603ac 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ኤንኤፍሲ"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ኤንኤፍሲ ተሰናክሏል"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ኤንኤፍሲ ነቅቷል"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"የማያ ገጽ ቀረጻ"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ጀምር"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"አቁም"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"መተግበሪያዎችን ለመቀየር ወደ ላይ ያንሸራትቱ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"መተግበሪያዎችን በፍጥነት ለመቀየር ወደ ቀኝ ይጎትቱ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"አጠቃላይ እይታን ቀያይር"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ሁሉንም አጽዳ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ያቀናብሩ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ጸጥ ያሉ ማሳወቂያዎች"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"ውይይቶች"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"አብጅ"</string>
     <string name="notification_done" msgid="6215117625922713976">"ተከናውኗል"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ቀልብስ"</string>
+    <string name="demote" msgid="6225813324237153980">"ይህን ማሳወቂያ ውይይት እንዳልሆነ ምልክት ያድርጉበት"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"ተወዳጅ"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"ተወዳጅ አታድርግ"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"ድምጽ ዝጋ"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"ድምጽ ክፈት"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"እንደ አረፋ አሳይ"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"አረፋዎችን አጥፋ"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"ወደ መነሻ ማያ ገጽ አክል"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"የማሳወቂያ መቆጣጠሪያዎች"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"የማሳወቂያ ማሸለቢያ አማራጮች"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f675265..c764004 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -109,7 +109,7 @@
     <string name="accessibility_camera_button" msgid="2938898391716647247">"الكاميرا"</string>
     <string name="accessibility_phone_button" msgid="4256353121703100427">"الهاتف"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"المساعد الصوتي"</string>
-    <string name="accessibility_unlock_button" msgid="122785427241471085">"إلغاء القفل"</string>
+    <string name="accessibility_unlock_button" msgid="122785427241471085">"فتح القفل"</string>
     <string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"في انتظار بصمة الإصبع"</string>
     <string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"فتح القفل بدون استخدام بصمة إصبعك"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"مسح الوجه"</string>
@@ -140,7 +140,7 @@
     <string name="face_dialog_looking_for_face" msgid="2656848512116189509">"جارٍ البحث عن وجهك…"</string>
     <string name="accessibility_face_dialog_face_icon" msgid="8335095612223716768">"رمز الوجه"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="5845799798708790509">"زر تكبير/تصغير للتوافق."</string>
-    <string name="accessibility_compatibility_zoom_example" msgid="2617218726091234073">"استخدام التكبير/التصغير لتحويل شاشة صغيرة إلى شاشة أكبر"</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="2617218726091234073">"استخدام التكبير أو التصغير لتحويل شاشة صغيرة إلى شاشة أكبر"</string>
     <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"تم توصيل البلوتوث."</string>
     <string name="accessibility_bluetooth_disconnected" msgid="7195823280221275929">"تم فصل البلوتوث."</string>
     <string name="accessibility_no_battery" msgid="3789287732041910804">"ليست هناك بطارية."</string>
@@ -399,6 +399,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"‏الاتصالات قصيرة المدى (NFC)"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"تم إيقاف الاتصال القريب المدى"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"تم تفعيل الاتصال القريب المدى"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"مرّر سريعًا لأعلى لتبديل التطبيقات"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"اسحب لليسار للتبديل السريع بين التطبيقات"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"تبديل \"النظرة العامة\""</string>
@@ -477,13 +483,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"إيقاف ميزة توفير شحن البطارية"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"سيتمكن تطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> من الوصول إلى كل المعلومات المرئية لك على الشاشة أو التي يتم تشغيلها على جهازك أثناء التسجيل أو الإرسال. ويشمل ذلك معلومات مثل كلمات المرور وتفاصيل الدفع والصور والرسائل والمقاطع الصوتية التي تشغِّلها."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ستتمكن الخدمة التي تقدّم هذه الوظيفة من الوصول إلى كل المعلومات المرئية لك على الشاشة أو التي يتم تشغيلها على جهازك أثناء التسجيل أو الإرسال. ويشمل ذلك معلومات مثل كلمات المرور وتفاصيل الدفع والصور والرسائل والمقاطع الصوتية التي تشغِّلها."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"هل تريد بدء التسجيل أو الإرسال؟"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"هل تريد بدء التسجيل أو الإرسال باستخدام <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>؟"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"عدم الإظهار مرة أخرى"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"محو الكل"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"إدارة"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"الإشعارات الصامتة"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"المحادثات"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"محو جميع الإشعارات الصامتة"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"الرجاء عدم الإزعاج\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
@@ -544,10 +550,10 @@
     <string name="branded_monitoring_description_app_personal" msgid="1703511985892688885">"أنت متصل بـ <xliff:g id="APPLICATION">%1$s</xliff:g>، الذي يمكنه مراقبة أنشطتك الشخصية على الشبكة، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب."</string>
     <string name="monitoring_description_app_work" msgid="3713084153786663662">"يخضع الملف الشخصي للعمل لإدارة <xliff:g id="ORGANIZATION">%1$s</xliff:g>. تم ربط الملف الشخصي بـ <xliff:g id="APPLICATION">%2$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nيمكنك الاتصال بالمشرف للحصول على مزيد من المعلومات."</string>
     <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"يخضع الملف الشخصي للعمل لإدارة <xliff:g id="ORGANIZATION">%1$s</xliff:g>. تم ربط هذا الملف الشخصي بـ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك، بما في ذلك الرسائل الإلكترونية والتطبيقات ومواقع الويب.\n\nتم ربطك بـ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>، الذي يمكنه مراقبة أنشطة شبكتك الشخصية."</string>
-    <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"‏إلغاء القفل باستمرار بواسطة TrustAgent"</string>
-    <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"سيظل الجهاز مقفلاً إلى أن يتم إلغاء قفله يدويًا"</string>
+    <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"‏فتح القفل باستمرار بواسطة TrustAgent"</string>
+    <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"سيظل الجهاز مقفلاً إلى أن يتم فتح قفله يدويًا"</string>
     <string name="hidden_notifications_title" msgid="1782412844777612795">"الحصول على الإشعارات بشكل أسرع"</string>
-    <string name="hidden_notifications_text" msgid="5899627470450792578">"الاطّلاع عليها قبل إلغاء القفل"</string>
+    <string name="hidden_notifications_text" msgid="5899627470450792578">"الاطّلاع عليها قبل فتح القفل"</string>
     <string name="hidden_notifications_cancel" msgid="4805370226181001278">"لا، شكرًا"</string>
     <string name="hidden_notifications_setup" msgid="2064795578526982467">"إعداد"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -702,6 +708,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"تخصيص"</string>
     <string name="notification_done" msgid="6215117625922713976">"تم"</string>
     <string name="inline_undo" msgid="9026953267645116526">"تراجع"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"عناصر التحكم في الإشعارات"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"خيارات تأجيل الإشعارات"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index d8a7b26..2fc393c 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC নিষ্ক্ৰিয় হৈ আছে"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম হৈ আছে"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"আনটো এপ্ ব্য়ৱহাৰ কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"খৰতকীয়াকৈ আনটো এপ্ ব্য়ৱহাৰ কৰিবলৈ সোঁফালে টানক"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"অৱলোকন ট’গল কৰক"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"বেটাৰি সঞ্চয়কাৰী অফ কৰক"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিংৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"এই সুবিধাটো প্ৰদান কৰা সেৱাটোৱে আপোনাৰ স্ক্ৰীনত দৃশ্যমান হোৱা অথবা ৰেকর্ডিং অথবা কাষ্টিংৰ সময়ত আপোনাৰ ডিভাইচত প্লে\' কৰা সকলো তথ্যলৈ এক্সেছ পাব। এইটোত পাছৱর্ড, পৰিশোধৰ সবিশেষ, ফট\', বার্তাসমূহ আৰু আপুনি প্লে\' কৰা অডিঅ\'ৰ দৰে তথ্য অন্তর্ভুক্ত হয়।"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ৰেকর্ডিং অথবা কাষ্টিং আৰম্ভ কৰিবনে?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ৰ জৰিয়তে ৰেকর্ডিং অথবা কাষ্টিং আৰম্ভ কৰিবনে ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"পুনৰাই নেদেখুৱাব"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"সকলো মচক"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"পৰিচালনা"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"নীৰৱ জাননীসমূহ"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"বাৰ্তালাপসমূহ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"সকলো নীৰৱ জাননী মচক"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"নিজৰ উপযোগিতা অনুসৰি"</string>
     <string name="notification_done" msgid="6215117625922713976">"সম্পন্ন হ’ল"</string>
     <string name="inline_undo" msgid="9026953267645116526">"আনডু কৰক"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"জাননীৰ নিয়ন্ত্ৰণসমূহ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"জাননীক স্নুজ কৰাৰ বিকল্পসমূহ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 7511a7f..de9c605 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC deaktiv edilib"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC aktiv edilib"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Tətbiqi dəyişmək üçün yuxarı sürüşdürün"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tətbiqləri cəld dəyişmək üçün sağa çəkin"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"İcmala Keçin"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Batareya Qənaətini deaktiv edin"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tətbiqinin yazma və ya yayım zamanı ekranda görünən və ya cihazdan oxudulan bütün məlumatlara girişi olacaq. Bura parollar, ödəniş detalları, fotolar, mesajlar və oxudulan audio kimi məlumatlar daxildir."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Bu funksiyanı təmin edən xidmətin yazma və ya yayım zamanı ekranda görünən və ya cihazdan oxudulan bütün məlumatlara girişi olacaq. Bura parollar, ödəniş detalları, fotolar, mesajlar və oxudulan audio kimi məlumatlar daxildir."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Yazma və ya yayımlama başladılsın?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ilə yazma və ya yayımlama başladılsın?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Daha göstərmə"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hamısını silin"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"İdarə edin"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Səssiz bildirişlər"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Söhbətlər"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Səssiz bildirişlərin hamısını silin"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Fərdiləşdirin"</string>
     <string name="notification_done" msgid="6215117625922713976">"Hazırdır"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Ləğv edin"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"bildiriş nəzarəti"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"bildiriş təxirə salma seçimləri"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 2b94d67..a895f35 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -393,6 +393,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Snimak ekrana"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Počnite"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Prevucite nagore da biste menjali aplikacije"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Prevucite udesno da biste brzo promenili aplikacije"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključi/isključi pregled"</string>
@@ -474,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Nečujna obaveštenja"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
@@ -692,6 +696,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Prilagodi"</string>
     <string name="notification_done" msgid="6215117625922713976">"Gotovo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Opozovi"</string>
+    <string name="demote" msgid="6225813324237153980">"Označi da ovo obaveštenje nije konverzacija"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Označi kao omiljeno"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Ukloni iz omiljenih"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Isključi zvuk"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Uključi zvuk"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Prikaži kao oblačić"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Isključi oblačiće"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Dodaj na početni ekran"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrole obaveštenja"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcije za odlaganje obaveštenja"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 35b0ddb..67aa899 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -397,6 +397,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC адключаны"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC уключаны"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Правядзіце ўверх, каб пераключыць праграмы"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Каб хутка пераключыцца паміж праграмамі, перацягніце ўправа"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Уключыць/выключыць агляд"</string>
@@ -473,13 +479,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Адключыць рэжым эканоміі зараду"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Падчас запісу ці трансляцыі праграма \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" будзе мець доступ да ўсёй інфармацыі, адлюстраванай на экране вашай прылады, ці той, якая праз яе прайграецца. Гэта інфармацыя ўключае паролі, звесткі пра аплату, фота, паведамленні і аўдыя, якое вы прайграяце."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Падчас запісу ці трансляцыі служба, якая забяспечвае работу гэтай функцыі, будзе мець доступ да ўсёй інфармацыі, адлюстраванай на экране вашай прылады, ці той, якая праз яе прайграецца. Гэта інфармацыя ўключае паролі, звесткі пра аплату, фота, паведамленні і аўдыя, якое вы прайграяце."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Пачаць запіс або трансляцыю?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Пачаць запіс або трансляцыю з дапамогай праграмы \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\"?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Не паказваць зноў"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Ачысціць усё"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Кіраваць"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Апавяшчэнні без гуку"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Размовы"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Выдаліць усе апавяшчэнні без гуку"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
@@ -698,6 +704,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Наладзіць"</string>
     <string name="notification_done" msgid="6215117625922713976">"Гатова"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Адрабіць"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"кіраванне апавяшчэннямі"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"параметры адкладвання апавяшчэнняў"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 26102fb..f83bf96 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"КБП"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Записване на екрана"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Старт"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Стоп"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Прекарайте пръст нагоре, за да превключите между приложенията"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Плъзнете надясно за бързо превключване между приложенията"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Превключване на общия преглед"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Изчистване на всички"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Управление"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Беззвучни известия"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Изчистване на всички беззвучни известия"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известията са поставени на пауза от режима „Не безпокойте“"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Персонализиране"</string>
     <string name="notification_done" msgid="6215117625922713976">"Готово"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Отмяна"</string>
+    <string name="demote" msgid="6225813324237153980">"Отбелязване, че известието не е за разговор"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Означаване като любим"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Не е любим"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Спиране"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Пускане"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Показване като балонче"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Изключване на балончетата"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Добавяне към началния екран"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"контроли за известията"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"опции за отлагане на известията"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index e17905a..10479b1 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC অক্ষম করা আছে"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম করা আছে"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"অন্য অ্যাপে যেতে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"একটি অ্যাপ ছেড়ে দ্রুত অন্য অ্যাপে যেতে ডান দিকে টেনে আনুন"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"\'এক নজরে\' বৈশিষ্ট্যটি চালু বা বন্ধ করুন"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ব্যাটারি সেভার বন্ধ করুন"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"রেকর্ড করা বা কাস্টিং করার সময় স্ক্রিনে দেখানো বা ডিভাইসে দেখানো সমস্ত তথ্যের অ্যাক্সেস <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-এর থাকবে। এর মধ্যে আপনার পাসওয়ার্ড, পেমেন্টের বিবরণ, ফটো, মেসেজ এবং যে অডিও আপনি চালান সেগুলি সম্পর্কিত তথ্য রয়েছে।"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"রেকর্ড করা বা কাস্টিং করার সময় আপনার স্ক্রিনে দেখানো বা ডিভাইসে চালানো হয়েছে এমন সমস্ত তথ্যের অ্যাক্সেস এই ফাংশন প্রদানকারী পরিষেবার কাছে থাকবে। এর মধ্যে আপনার পাসওয়ার্ড, পেমেন্টের বিবরণ, ফটো, মেসেজ এবং যে অডিও আপনি চালান সেগুলি সম্পর্কিত তথ্য রয়েছে।"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"রেকর্ড অথবা কাস্টিং শুরু করতে চান?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> দিয়ে রেকর্ড করা বা কাস্টিং শুরু করবেন?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"আর দেখাবেন না"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"সবকিছু সাফ করুন"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"পরিচালনা করুন"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"নীরব বিজ্ঞপ্তি"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"কথোপকথন"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"সব নীরব বিজ্ঞপ্তি মুছুন"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'বিরক্ত করবে না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"কাস্টমাইজ করুন"</string>
     <string name="notification_done" msgid="6215117625922713976">"সম্পন্ন"</string>
     <string name="inline_undo" msgid="9026953267645116526">"আগের অবস্থায় ফিরে যান"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"বিজ্ঞপ্তির নিয়ন্ত্রণগুলি"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"বিজ্ঞপ্তি মনে করিয়ে দেওয়ার বিকল্পগুলি"</string>
@@ -886,7 +908,7 @@
     <string name="notification_channel_general" msgid="4384774889645929705">"সাধারণ বার্তাগুলি"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"স্টোরেজ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"হিন্ট"</string>
-    <string name="instant_apps" msgid="8337185853050247304">"ঝটপট অ্যাপ"</string>
+    <string name="instant_apps" msgid="8337185853050247304">"ইনস্ট্যান্ট অ্যাপ"</string>
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> চলছে"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"অ্যাপটি ইনস্টল না করে চালু করা হয়েছে।"</string>
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"অ্যাপটি ইনস্টল না করে চালু করা হয়েছে। আরও জানতে ট্যাপ করুন।"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 5851011..6c89d97 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -393,6 +393,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Snimanje ekrana"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Započnite"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Prevucite prema gore za promjenu aplikacije"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Prevucite udesno za brzu promjenu aplikacija"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Pregled uključivanja/isključivanja"</string>
@@ -474,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Očisti sve"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Nečujna obavještenja"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obriši sva nečujna obavještenja"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
@@ -694,6 +698,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Prilagodi"</string>
     <string name="notification_done" msgid="6215117625922713976">"Gotovo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Opozovi"</string>
+    <string name="demote" msgid="6225813324237153980">"Označi da ovo obavještenje nije razgovor"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Omiljeno"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Ukloni iz omiljenog"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Isključi zvuk"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Uključi zvuk"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Prikaži kao oblačić"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Isključi oblačiće"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Dodaj na početni ekran"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrole obavještenja"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcije za odgodu obavještenja"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 9fb7230..f675e20 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"L\'NFC està desactivada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"L\'NFC està activada"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravació de la pantalla"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inicia"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Atura"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Llisca cap amunt per canviar d\'aplicació"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrossega el dit cap a la dreta per canviar ràpidament d\'aplicació"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activa o desactiva Aplicacions recents"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Esborra-ho tot"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestiona"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificacions silencioses"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificacions pausades pel mode No molestis"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalitza"</string>
     <string name="notification_done" msgid="6215117625922713976">"Fet"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Desfés"</string>
+    <string name="demote" msgid="6225813324237153980">"Marca que la notificació no és una conversa"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Marca com a preferida"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Desmarca com a preferida"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Silencia"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Deixa de silenciar"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostra com a bombolla"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desactiva les bombolles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Afegeix a la pantalla d\'inici"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"controls de notificació"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcions per posposar la notificació"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 30724f8..354ccf4 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -395,6 +395,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je vypnuto"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je zapnuto"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Záznam obrazovky"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Spustit"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ukončit"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Přejetím nahoru přepnete aplikace"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Přetažením doprava rychle přepnete aplikace"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Přepnout přehled"</string>
@@ -477,6 +480,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Smazat vše"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Spravovat"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tichá oznámení"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzace"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazat všechna tichá oznámení"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Oznámení jsou pozastavena režimem Nerušit"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
@@ -695,6 +699,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Upravit"</string>
     <string name="notification_done" msgid="6215117625922713976">"Hotovo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Zpět"</string>
+    <string name="demote" msgid="6225813324237153980">"Označit, že toto oznámení není součástí konverzace"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Přidat mezi oblíbené"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Odebrat z oblíbených"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Ignorovat"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Přestat ignorovat"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Zobrazit jako bublinu"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Vypnout bubliny"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Přidat na plochu"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"Nastavení oznámení"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"Možnosti odložení oznámení"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index e20a276..04e83d4 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er deaktiveret"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er aktiveret"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Optag skærm"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Stryg opad for at skifte apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Træk til højre for hurtigt at skifte app"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Slå Oversigt til/fra"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Ryd alle"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Lydløse notifikationer"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ryd alle lydløse notifikationer"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikationer er sat på pause af Forstyr ikke"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Tilpas"</string>
     <string name="notification_done" msgid="6215117625922713976">"Udfør"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Fortryd"</string>
+    <string name="demote" msgid="6225813324237153980">"Markér denne notifikation som ikke en samtale"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Angiv som favorit"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Fjern som favorit"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Slå lyden fra"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Slå lyden til"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Vis som boble"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Slå bobler fra"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Føj til startskærm"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrolelementer til notifikationer"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"Indstillinger for udsættelse"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 7defdc1..baf3e7c 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -395,6 +395,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ist deaktiviert"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ist aktiviert"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Nach oben wischen, um Apps zu wechseln"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Zum schnellen Wechseln der Apps nach rechts ziehen"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Übersicht ein-/ausblenden"</string>
@@ -469,13 +475,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Energiesparmodus deaktivieren"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Die App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise Passwörter, Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Der Anbieter dieser App erhält Zugriff auf alle Informationen, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden, während du aufnimmst oder streamst. Dazu gehören beispielsweise Passwörter, Zahlungsdetails, Fotos, Nachrichten und Audioinhalte."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Aufnahme oder Stream starten?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Aufnehmen oder Streamen mit der App \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" starten?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Nicht mehr anzeigen"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Alle löschen"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Verwalten"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Lautlose Benachrichtigungen"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle lautlosen Benachrichtigungen löschen"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Benachrichtigungen durch \"Bitte nicht stören\" pausiert"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
@@ -694,6 +700,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Anpassen"</string>
     <string name="notification_done" msgid="6215117625922713976">"Fertig"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Rückgängig machen"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> – <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"Benachrichtigungseinstellungen"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"Optionen für spätere Erinnerung bei Benachrichtigungen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 14da101..45ad302 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Το NFC είναι απενεργοποιημένο"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Το NFC είναι ενεργοποιημένο"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Εγγραφή οθόνης"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Έναρξη"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Διακοπή"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Σύρετε προς τα επάνω για εναλλαγή των εφαρμογών"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Σύρετε προς τα δεξιά για γρήγορη εναλλαγή εφαρμογών"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Εναλλαγή επισκόπησης"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Διαγραφή όλων"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Διαχείριση"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Ειδοποιήσεις σε σίγαση"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Συνομιλίες"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Διαγραφή όλων των ειδοποιήσεων σε σίγαση"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία \"Μην ενοχλείτε\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Προσαρμογή"</string>
     <string name="notification_done" msgid="6215117625922713976">"Τέλος"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Αναίρεση"</string>
+    <string name="demote" msgid="6225813324237153980">"Επισήμανση αυτής της ειδοποίησης ως μη συνομιλίας"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Αγαπημένη"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Μη αγαπημένη"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Σίγαση"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Κατάργηση σίγασης"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Εμφάνιση ως φούσκας"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Απενεργοποίηση φουσκών"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Προσθήκη στην αρχική οθόνη"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"στοιχεία ελέγχου ειδοποιήσεων"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"επιλογές αναβολής ειδοποιήσεων"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 5f38830..b6a5d15 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Screen record"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swipe up to switch apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Drag right to quickly switch apps"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Silent notifications"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -516,7 +520,7 @@
     <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> uses <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> to manage your device."</string>
     <string name="monitoring_description_do_body" msgid="7700878065625769970">"Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
-    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Find out more"</string>
+    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Learn more"</string>
     <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"You\'re connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Customise"</string>
     <string name="notification_done" msgid="6215117625922713976">"Done"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Undo"</string>
+    <string name="demote" msgid="6225813324237153980">"Mark this notification as not a conversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favourite"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Unfavourite"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Mute"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Unmute"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Show as bubble"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Turn off bubbles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Add to home screen"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"notification snooze options"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 1da1df3..e194e69 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Screen record"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swipe up to switch apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Drag right to quickly switch apps"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Silent notifications"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -516,7 +520,7 @@
     <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> uses <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> to manage your device."</string>
     <string name="monitoring_description_do_body" msgid="7700878065625769970">"Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
-    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Find out more"</string>
+    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Learn more"</string>
     <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"You\'re connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Customise"</string>
     <string name="notification_done" msgid="6215117625922713976">"Done"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Undo"</string>
+    <string name="demote" msgid="6225813324237153980">"Mark this notification as not a conversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favourite"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Unfavourite"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Mute"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Unmute"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Show as bubble"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Turn off bubbles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Add to home screen"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"notification snooze options"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 5f38830..b6a5d15 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Screen record"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swipe up to switch apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Drag right to quickly switch apps"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Silent notifications"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -516,7 +520,7 @@
     <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> uses <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> to manage your device."</string>
     <string name="monitoring_description_do_body" msgid="7700878065625769970">"Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
-    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Find out more"</string>
+    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Learn more"</string>
     <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"You\'re connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Customise"</string>
     <string name="notification_done" msgid="6215117625922713976">"Done"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Undo"</string>
+    <string name="demote" msgid="6225813324237153980">"Mark this notification as not a conversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favourite"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Unfavourite"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Mute"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Unmute"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Show as bubble"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Turn off bubbles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Add to home screen"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"notification snooze options"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 5f38830..b6a5d15 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Screen record"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swipe up to switch apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Drag right to quickly switch apps"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Toggle Overview"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Silent notifications"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -516,7 +520,7 @@
     <string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> uses <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> to manage your device."</string>
     <string name="monitoring_description_do_body" msgid="7700878065625769970">"Your admin can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
-    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Find out more"</string>
+    <string name="monitoring_description_do_learn_more" msgid="645149183455573790">"Learn more"</string>
     <string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"You\'re connected to <xliff:g id="VPN_APP">%1$s</xliff:g>, which can monitor your network activity, including emails, apps and websites."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Customise"</string>
     <string name="notification_done" msgid="6215117625922713976">"Done"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Undo"</string>
+    <string name="demote" msgid="6225813324237153980">"Mark this notification as not a conversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favourite"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Unfavourite"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Mute"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Unmute"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Show as bubble"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Turn off bubbles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Add to home screen"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"notification controls"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"notification snooze options"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index fd3ff45..e3a569a 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎NFC‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎NFC is disabled‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎NFC is enabled‎‏‎‎‏‎"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎Screen Record‎‏‎‎‏‎"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎Start‎‏‎‎‏‎"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎Stop‎‏‎‎‏‎"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎Swipe up to switch apps‎‏‎‎‏‎"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎Drag right to quickly switch apps‎‏‎‎‏‎"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎Toggle Overview‎‏‎‎‏‎"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎Clear all‎‏‎‎‏‎"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎Manage‎‏‎‎‏‎"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎Silent notifications‎‏‎‎‏‎"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎Conversations‎‏‎‎‏‎"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎Clear all silent notifications‎‏‎‎‏‎"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎Notifications paused by Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎Start now‎‏‎‎‏‎"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎Customize‎‏‎‎‏‎"</string>
     <string name="notification_done" msgid="6215117625922713976">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎Done‎‏‎‎‏‎"</string>
     <string name="inline_undo" msgid="9026953267645116526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎Undo‎‏‎‎‏‎"</string>
+    <string name="demote" msgid="6225813324237153980">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎Mark this notification as not a conversation‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎Favorite‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎Unfavorite‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎Mute‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎Unmute‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎Show as bubble‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎Turn off bubbles‎‏‎‎‏‎"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‎Add to home screen‎‏‎‎‏‎"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎notification controls‎‏‎‎‏‎"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎notification snooze options‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index eb27998f..255db92 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"La tecnología NFC está inhabilitada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La tecnología NFC está habilitada"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Grabar pantalla"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Detener"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Desliza el dedo hacia arriba para cambiar de app"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra a la derecha para cambiar aplicaciones rápidamente"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Ocultar o mostrar Recientes"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrar"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificaciones silenciosas"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string>
     <string name="notification_done" msgid="6215117625922713976">"Listo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Deshacer"</string>
+    <string name="demote" msgid="6225813324237153980">"Marcar que la notificación no es una conversación"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Marcar como favorita"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Borrar de las favoritas"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Silenciar"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Dejar de silenciar"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostrar como cuadro"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desactivar cuadros"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Agregar a la pantalla principal"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"controles de notificación"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opciones para posponer notificaciones"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 731d727..d1d959c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -389,8 +389,11 @@
     <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Al anochecer"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
-    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"La conexión NFC está inhabilitada"</string>
-    <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La conexión NFC está habilitada"</string>
+    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"El NFC está desactivado"</string>
+    <string name="quick_settings_nfc_on" msgid="1004976611203202230">"El NFC está activado"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Grabación de la pantalla"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inicio"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Detener"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Desliza el dedo hacia arriba para cambiar de aplicación"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra hacia la derecha para cambiar rápidamente de aplicación"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Mostrar u ocultar aplicaciones recientes"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificaciones silenciadas"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciadas"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo No molestar"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar ahora"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string>
     <string name="notification_done" msgid="6215117625922713976">"Listo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Deshacer"</string>
+    <string name="demote" msgid="6225813324237153980">"Marcar esta notificación como que no es una conversación"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favorita"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Quitar de favoritos"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Silenciar"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Activar sonido"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostrar como burbuja"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desactivar las burbujas"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Añadir a la pantalla de inicio"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"Controles de las notificaciones"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"Opciones para posponer las notificaciones"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ab86e03..6f69a17 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on keelatud"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on lubatud"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Rakenduste vahetamiseks pühkige üles"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Lohistage paremale, et rakendusi kiiresti vahetada"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Lehe Ülevaade sisse- ja väljalülitamine"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tühjenda kõik"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Haldamine"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Hääletud märguanded"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Vestlused"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kustuta kõik hääletud märguanded"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Režiim Mitte segada peatas märguanded"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Kohandamine"</string>
     <string name="notification_done" msgid="6215117625922713976">"Valmis"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Võta tagasi"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"märguannete juhtnupud"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"märguannete edasilükkamise valikud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 18ac031..1b89c5a 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -57,12 +57,12 @@
     <string name="label_view" msgid="6815442985276363364">"Ikusi"</string>
     <string name="always_use_device" msgid="210535878779644679">"Ireki <xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g> konektatzen den guztietan"</string>
     <string name="always_use_accessory" msgid="1977225429341838444">"Ireki <xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> konektatzen den guztietan"</string>
-    <string name="usb_debugging_title" msgid="8274884945238642726">"USB arazketa onartu?"</string>
+    <string name="usb_debugging_title" msgid="8274884945238642726">"USB bidezko arazketa onartu?"</string>
     <string name="usb_debugging_message" msgid="5794616114463921773">"Ordenagailuaren RSA gakoaren erreferentzia-gako digitala hau da:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="4003121804294739548">"Eman beti ordenagailu honetatik arazteko baimena"</string>
     <string name="usb_debugging_allow" msgid="1722643858015321328">"Baimendu"</string>
-    <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ez da onartzen USB arazketa"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
+    <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Ez da onartzen USB bidezko arazketa"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB bidezko arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
     <string name="usb_contaminant_title" msgid="894052515034594113">"Desgaitu egin da USB ataka"</string>
     <string name="usb_contaminant_message" msgid="7730476585174719805">"USB ataka desgaitu egin da gailua likido edo zikinkeriengandik babesteko, eta ez du hautemango osagarririk.\n\nJakinarazpen bat jasoko duzu USB ataka berriz erabiltzeko moduan dagoenean."</string>
     <string name="usb_port_enabled" msgid="531823867664717018">"USB ataka gaitu da kargagailuak eta osagarriak hautemateko"</string>
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Desgaituta dago NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Gaituta dago NFC"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Egin gora aplikazioa aldatzeko"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastatu eskuinera aplikazioa azkar aldatzeko"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Aldatu ikuspegi orokorra"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Garbitu guztiak"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Kudeatu"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Soinurik gabeko jakinarazpenak"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Elkarrizketak"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Pertsonalizatu"</string>
     <string name="notification_done" msgid="6215117625922713976">"Eginda"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Desegin"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"jakinarazpena kontrolatzeko aukerak"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"jakinarazpena atzeratzeko aukerak"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 77164b7..2b76557 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‏NFC غیرفعال است"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‏NFC فعال است"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"برای تغییر برنامه‌ها،‌ تند به بالا بکشید"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"برای جابه‌جایی سریع میان برنامه‌ها، به چپ بکشید"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"تغییر وضعیت نمای کلی"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"پاک کردن همه موارد"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"مدیریت"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"اعلان‌های بی‌صدا"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"مکالمه‌ها"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"پاک کردن همه اعلان‌های بی‌صدا"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع شود"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"سفارشی کردن"</string>
     <string name="notification_done" msgid="6215117625922713976">"تمام"</string>
     <string name="inline_undo" msgid="9026953267645116526">"واگرد"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"کنترل‌های اعلان"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"گزینه‌های تعویق اعلان"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e70b4d5..9b76f39 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on poistettu käytöstä"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on käytössä"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Vaihda sovellusta pyyhkäisemällä ylös"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Vaihda sovellusta nopeasti vetämällä oikealle"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Näytä/piilota viimeisimmät"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Poista kaikki"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Muuta asetuksia"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Hiljaiset ilmoitukset"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Keskustelut"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Muokkaa"</string>
     <string name="notification_done" msgid="6215117625922713976">"Valmis"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Kumoa"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"Ilmoitusten hallinta"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"Ilmoitusten torkkuasetukset"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index ead29c0..55eb39e 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC activée"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Enregistrement d\'écran"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Démarrer"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Arrêter"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Balayez vers le haut pour changer d\'application"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Balayez l\'écran vers la droite pour changer rapidement d\'application"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Basculer l\'aperçu"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifications silencieuses"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personnaliser"</string>
     <string name="notification_done" msgid="6215117625922713976">"Terminé"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Annuler"</string>
+    <string name="demote" msgid="6225813324237153980">"Marquer cette notification comme n\'étant pas une conversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Ajouter aux favoris"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Supprimer des favoris"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Ignorer"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Réactiver"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Afficher comme bulle"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Désactiver les bulles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Ajouter à l\'écran d\'accueil"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"paramètres des notifications"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"options de répétition des notifications"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b701276..5b12612 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -389,8 +389,11 @@
     <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Activé la nuit"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string>
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
-    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"La technologie NFC est désactivée"</string>
+    <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La technologie NFC est activée"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Enregistrement de l\'écran"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Démarrer"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Arrêter"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Balayer l\'écran vers le haut pour changer d\'application"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Déplacer vers la droite pour changer rapidement d\'application"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activer/Désactiver l\'aperçu"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifications silencieuses"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personnaliser"</string>
     <string name="notification_done" msgid="6215117625922713976">"Terminé"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Annuler"</string>
+    <string name="demote" msgid="6225813324237153980">"Marquer cette notification comme n\'étant pas une conversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Ajouter aux favoris"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Supprimer des favoris"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Couper le son"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Réactiver le son"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Afficher sous forme de bulle"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Désactiver les bulles"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Ajouter à l\'écran d\'accueil"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> : <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"paramètres des notifications"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"options de répétition des notifications"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 464684e..74ee202 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A opción NFC está desactivada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A opción NFC está activada"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravación da pantalla"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Deter"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Pasar o dedo cara arriba para cambiar de aplicación"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra cara á dereita para cambiar de aplicacións rapidamente"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activar/desactivar Visión xeral"</string>
@@ -465,13 +468,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Desactivar a función Aforro de batería"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> terá acceso a toda a información visible na pantalla ou reproducida desde o teu dispositivo mentres graves ou emitas contido. Isto inclúe información como contrasinais, detalles de pago, fotos, mensaxes e o audio que reproduzas."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"O servizo que proporciona esta función terá acceso a toda a información visible na pantalla ou reproducida desde o teu dispositivo mentres graves ou emitas contido. Isto inclúe información como contrasinais, detalles de pago, fotos, mensaxes e o audio que reproduzas."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Queres iniciar a gravación ou a emisión?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Queres comezar a gravar ou emitir contido con <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Non mostrar outra vez"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todas"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificacións silenciadas"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borra todas as notificacións silenciadas"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"O modo Non molestar puxo en pausa as notificacións"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -690,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string>
     <string name="notification_done" msgid="6215117625922713976">"Feito"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Desfacer"</string>
+    <string name="demote" msgid="6225813324237153980">"Marcar que esta notificación non é unha conversa"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Engadir a favoritos"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Quitar de favoritos"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Silenciar"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Activar son"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostrar como unha burbulla"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desactivar burbullas"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Engadir á pantalla de inicio"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"controis de notificacións"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcións para adiar notificacións"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index de6b3793..4b5dd25 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -37,7 +37,7 @@
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"બૅટરી સેવર વિશે"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ચાલુ કરો"</string>
     <string name="battery_saver_start_action" msgid="4553256017945469937">"બૅટરી સેવર ચાલુ કરો"</string>
-    <string name="status_bar_settings_settings_button" msgid="534331565185171556">"સેટિંગ્સ"</string>
+    <string name="status_bar_settings_settings_button" msgid="534331565185171556">"સેટિંગ"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"વાઇ-ફાઇ"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ઑટો રોટેટ સ્ક્રીન"</string>
     <string name="status_bar_settings_mute_label" msgid="914392730086057522">"મ્યૂટ કરો"</string>
@@ -224,7 +224,7 @@
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"નોટિફિકેશન શેડ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ઝડપી સેટિંગ્સ."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"લૉક સ્ક્રીન."</string>
-    <string name="accessibility_desc_settings" msgid="6728577365389151969">"સેટિંગ્સ"</string>
+    <string name="accessibility_desc_settings" msgid="6728577365389151969">"સેટિંગ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1748675199348914194">"ઝલક."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"કાર્ય લૉક સ્ક્રીન"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"બંધ કરો"</string>
@@ -295,7 +295,7 @@
     </plurals>
     <string name="notification_summary_message_format" msgid="5158219088501909966">"<xliff:g id="CONTACT_NAME">%1$s</xliff:g>: <xliff:g id="MESSAGE_CONTENT">%2$s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"સૂચનાઓની સેટિંગ્સ"</string>
-    <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> સેટિંગ્સ"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> સેટિંગ"</string>
     <string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"સ્ક્રીન આપમેળે ફરશે."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"સ્ક્રીન લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"સ્ક્રીન પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
@@ -333,7 +333,7 @@
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"મીડિયા ઉપકરણ"</string>
     <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ફક્ત કટોકટીના કૉલ્સ"</string>
-    <string name="quick_settings_settings_label" msgid="2214639529565474534">"સેટિંગ્સ"</string>
+    <string name="quick_settings_settings_label" msgid="2214639529565474534">"સેટિંગ"</string>
     <string name="quick_settings_time_label" msgid="3352680970557509303">"સમય"</string>
     <string name="quick_settings_user_label" msgid="1253515509432672496">"હું"</string>
     <string name="quick_settings_user_title" msgid="8673045967216204537">"વપરાશકર્તા"</string>
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC અક્ષમ કરેલ છે"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC સક્ષમ કરેલ છે"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ઍપ સ્વિચ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ઍપને ઝડપથી સ્વિચ કરવા માટે જમણે ખેંચો"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ઝલકને ટૉગલ કરો"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"બધુ સાફ કરો"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"મેનેજ કરો"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"સાઇલન્ટ નોટિફિકેશન"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"વાતચીત"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"હવે પ્રારંભ કરો"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"કસ્ટમાઇઝ કરો"</string>
     <string name="notification_done" msgid="6215117625922713976">"થઈ ગયું"</string>
     <string name="inline_undo" msgid="9026953267645116526">"રદ કરો"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"સૂચના નિયંત્રણો"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"સૂચના સ્નૂઝ કરવાના વિકલ્પો"</string>
@@ -885,7 +908,7 @@
     <string name="notification_channel_general" msgid="4384774889645929705">"સામાન્ય સંદેશા"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"સ્ટોરેજ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"હિન્ટ"</string>
-    <string name="instant_apps" msgid="8337185853050247304">"ઝટપટ ઍપ્લિકેશનો"</string>
+    <string name="instant_apps" msgid="8337185853050247304">"ઝટપટ ઍપ્લિકેશન"</string>
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> ચાલી રહી છે"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે."</string>
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે. વધુ જાણવા માટે ટૅપ કરો."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 706f8b3..c22d234 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"एनएफ़सी"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC बंद है"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC चालू है"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ऐप्लिकेशन बदलने के लिए ऊपर स्वाइप करें"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ऐप्लिकेशन को झटपट स्विच करने के लिए उसे दाईं ओर खींचें और छोड़ें"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"खास जानकारी टॉगल करें"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"बैटरी सेवर बंद करें"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> आपकी स्क्रीन पर दिख रही या आपके डिवाइस पर चलाई जा रही जानकारी ऐक्सेस कर सकता है. इसमें पासवर्ड, पैसे चुकाने का ब्यौरा, फ़ोटो, मैसेज, और चलाए गए ऑडियो जैसी जानकारी शामिल है."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"रिकॉर्ड या कास्ट करते समय, वह सेवा जो यह फ़ंक्शन उपलब्ध कराती है, आपके डिवाइस पर चलाई जा रही या स्क्रीन पर दिख रही जानकारी को ऐक्सेस कर सकती है. इसमें पासवर्ड, पैसे चुकाने का ब्यौरा, फ़ोटो, मैसेज, और चलाए गए ऑडियो जैसी जानकारी शामिल है."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रिकॉर्डिंग या कास्ट करना शुरू करें?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> का इस्तेमाल करके रिकॉर्ड और कास्ट करना शुरू करें?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"फिर से न दिखाएं"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"सभी को हटाएं"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"प्रबंधित करें"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"बिना आवाज़ या वाइब्रेशन वाली सूचनाएं"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"अब शुरू करें"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"पसंद के मुताबिक बनाएं"</string>
     <string name="notification_done" msgid="6215117625922713976">"हो गया"</string>
     <string name="inline_undo" msgid="9026953267645116526">"पहले जैसा करें"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"सूचना नियंत्रण"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"सूचना को स्नूज़ (थोड़ी देर के लिए चुप करना) करने के विकल्प"</string>
@@ -886,7 +908,7 @@
     <string name="notification_channel_general" msgid="4384774889645929705">"सामान्य संदेश"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"जगह"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"संकेत"</string>
-    <string name="instant_apps" msgid="8337185853050247304">"इंस्टेंट ऐप"</string>
+    <string name="instant_apps" msgid="8337185853050247304">"झटपट ऐप्लिकेशन"</string>
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> चल रहा है"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है."</string>
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है. ज़्यादा जानने के लिए टैप करें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index bf027fb..1286709 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -393,6 +393,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Snimač zaslona"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Početak"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavi"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Prijeđite prstom prema gore da biste promijenili aplikaciju"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Povucite udesno da biste brzo promijenili aplikaciju"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Uključivanje/isključivanje pregleda"</string>
@@ -474,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši sve"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Bešumne obavijesti"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Izbriši sve bešumne obavijesti"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni sad"</string>
@@ -692,6 +696,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Prilagodi"</string>
     <string name="notification_done" msgid="6215117625922713976">"Gotovo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Poništi"</string>
+    <string name="demote" msgid="6225813324237153980">"Označi da ova obavijest nije razgovor"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favorit"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Nije omiljeno"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Zanemari"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Opozovi"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Prikaži u oblačiću"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Isključi oblačiće"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Dodavanje na početni zaslon"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrole obavijesti"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcije odgode obavijesti"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 90c8a1a..a3b6d3f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Képernyő rögzítése"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Kezdés"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Leállítás"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Váltás az alkalmazások között felfelé csúsztatással"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Húzza jobbra az ujját az alkalmazások közötti gyors váltáshoz"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Áttekintés be- és kikapcsolása"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Az összes törlése"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Kezelés"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Néma értesítések"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Beszélgetések"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Az összes néma értesítés törlése"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Személyre szabás"</string>
     <string name="notification_done" msgid="6215117625922713976">"Kész"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Visszavonás"</string>
+    <string name="demote" msgid="6225813324237153980">"Értesítés megjelölése mint nem beszélgetés"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Kedvenc"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Törlés a kedvencek közül"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Némítás"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Némítás feloldása"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Megjelenítés buborékként"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Buborékok kikapcsolása"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Hozzáadás a kezdőképernyőhöz"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> – <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"értesítésvezérlők"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"értesítések halasztási beállításai"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index f25f6ae..5c73ed1 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-ն անջատված է"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-ն միացված է"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Սահեցրեք վերև՝ մյուս հավելվածին անցնելու համար"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Քաշեք աջ՝ հավելվածների միջև անցնելու համար"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Միացնել/անջատել համատեսքը"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Անջատել մարտկոցի տնտեսումը"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Ձայնագրման և հեռարձակման ընթացքում <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածին հասանելի կլինեն ձեր սարքի էկրանին ցուցադրվող տեղեկությունները և ձեր սարքով նվագարկվող նյութերը։ Սա ներառում է այնպիսի տեղեկություններ, ինչպիսիք են, օրինակ, գաղտնաբառերը, վճարային տվյալները, լուսանկարները, հաղորդագրությունները և նվագարկվող աուդիո ֆայլերը։"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Ձայնագրման և հեռարձակման ընթացքում ծառայությունների մատակարարին հասանելի կլինեն ձեր սարքի էկրանին ցուցադրվող տեղեկությունները և ձեր սարքով նվագարկվող նյութերը։ Սա ներառում է այնպիսի տեղեկություններ, ինչպիսիք են, օրինակ, գաղտնաբառերը, վճարային տվյալները, լուսանկարները, հաղորդագրությունները և նվագարկվող աուդիո ֆայլերը։"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Սկսե՞լ ձայնագրումը կամ հեռարձակումը"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Սկսե՞լ ձայնագրումը կամ հեռարձակումը <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածով"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Այլևս ցույց չտալ"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Մաքրել բոլորը"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Կառավարել"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Անձայն ծանուցումներ"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Խոսակցություններ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ջնջել բոլոր անձայն ծանուցումները"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Կարգավորել"</string>
     <string name="notification_done" msgid="6215117625922713976">"Պատրաստ է"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Հետարկել"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ծանուցման կառավարներ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ծանուցման հետաձգման ընտրանքներ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 835725f..bad3e67 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dinonaktifkan"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC diaktifkan"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Rekaman Layar"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Mulai"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Berhenti"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Geser ke atas untuk beralih aplikasi"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tarik ke kanan untuk beralih aplikasi dengan cepat"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Aktifkan Ringkasan"</string>
@@ -465,13 +468,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Nonaktifkan Penghemat Baterai"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan memiliki akses ke semua informasi yang terlihat di layar atau diputar dari perangkat saat merekam atau melakukan transmisi. Ini mencakup informasi seperti sandi, detail pembayaran, foto, pesan, dan audio yang Anda putar."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Layanan yang menyediakan fungsi ini akan memiliki akses ke semua informasi yang terlihat di layar atau diputar dari perangkat saat merekam atau melakukan transmisi. Ini mencakup informasi seperti sandi, detail pembayaran, foto, pesan, dan audio yang Anda putar."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Mulai merekam atau melakukan transmisi?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Mulai merekam atau melakukan transmisi dengan <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Jangan tampilkan lagi"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hapus semua"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Kelola"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifikasi senyap"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Percakapan"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hapus semua notifikasi senyap"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikasi dijeda oleh mode Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
@@ -690,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Sesuaikan"</string>
     <string name="notification_done" msgid="6215117625922713976">"Selesai"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Urungkan"</string>
+    <string name="demote" msgid="6225813324237153980">"Tandai notifikasi ini sebagai bukan percakapan"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favorit"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Batal favoritkan"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Bisukan"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Bunyikan"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Tampilkan sebagai balon"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Nonaktifkan balon"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Tambahkan ke layar utama"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrol notifikasi"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opsi tunda notifikasi"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 95e4010..68f04fb 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Slökkt á NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Kveikt á NFC"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Skjáupptaka"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Hefja"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stöðva"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Strjúktu upp til að skipta á milli forrita"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Dragðu til hægri til að skipta hratt á milli forrita"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Kveikja/slökkva á yfirliti"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hreinsa allt"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Stjórna"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Þöglar tilkynningar"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtöl"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hreinsa allar þöglar tilkynningar"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Sérsníða"</string>
     <string name="notification_done" msgid="6215117625922713976">"Lokið"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Afturkalla"</string>
+    <string name="demote" msgid="6225813324237153980">"Merkja þessa tilkynningu sem „ekki samtal“"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Eftirlæti"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Fjarlægja úr eftirlæti"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Þagga"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Hætta að þagga"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Sýna sem blöðru"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Slökkva á blöðrum"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Bæta á heimaskjá"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"tilkynningastýringar"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"þöggunarstillingar tilkynninga"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 4cec980..bdf93fa 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC non attiva"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC attiva"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Registrazione dello schermo"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inizia"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Interrompi"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Scorri verso l\'alto per passare ad altre app"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Trascina verso destra per cambiare velocemente app"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Attiva/disattiva la panoramica"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Cancella tutto"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestisci"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifiche silenziose"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversazioni"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Cancella tutte le notifiche silenziose"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifiche messe in pausa in base alla modalità Non disturbare"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizza"</string>
     <string name="notification_done" msgid="6215117625922713976">"Fine"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Annulla"</string>
+    <string name="demote" msgid="6225813324237153980">"Contrassegna questa notifica come \"non è una conversazione\""</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Aggiungi ai preferiti"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Rimuovi dai preferiti"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Disattiva"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Riattiva"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostra sotto forma di fumetto"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Disattiva i fumetti"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Aggiungi a schermata Home"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"gestione delle notifiche"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opzioni di posticipazione notifiche"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 949c8db..9cfd0b3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -395,6 +395,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‏NFC מושבת"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‏NFC מופעל"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"יש להחליק מעלה כדי להחליף אפליקציות"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"יש לגרור ימינה כדי לעבור במהירות בין אפליקציות"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"החלפת מצב של מסכים אחרונים"</string>
@@ -477,6 +483,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכל"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"התראות שקטות"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ניקוי כל ההתראות השקטות"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"התחל כעת"</string>
@@ -695,6 +702,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"התאמה אישית"</string>
     <string name="notification_done" msgid="6215117625922713976">"סיום"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ביטול"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"בקרת התראות"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"אפשרויות של דחיית התראות לטיפול בהמשך"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 2f1ad09..0c57372 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC は無効です"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC は有効です"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"アプリを切り替えるには上にスワイプ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"右にドラッグするとアプリを素早く切り替えることができます"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"概要を切り替え"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"バッテリー セーバーを OFF"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>は、記録中やキャスト中に画面上に表示またはデバイスから再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などの情報が含まれます。"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"この機能を提供するサービスは、記録中やキャスト中に画面上に表示またはデバイスから再生されるすべての情報にアクセスできます。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などの情報が含まれます。"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"記録やキャストを開始しますか?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>で記録やキャストを開始しますか?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"次回から表示しない"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"すべて消去"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"サイレント通知"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"会話"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"サイレント通知がすべて消去されます"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"サイレント モードにより通知は一時停止中です"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"カスタマイズ"</string>
     <string name="notification_done" msgid="6215117625922713976">"完了"</string>
     <string name="inline_undo" msgid="9026953267645116526">"元に戻す"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"通知管理"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"通知スヌーズ設定"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 7754572..a3827d2 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC გათიშულია"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ჩართულია"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"გადაფურცლეთ ზემოთ აპების გადასართავად"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"აპების სწრაფად გადასართავად ჩავლებით გადაიტანეთ მარჯვნივ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"მიმოხილვის გადართვა"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ბატარეის დამზოგის გამორთვა"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ს ექნება წვდომა ყველა ინფორმაციაზე, რომელიც თქვენს ეკრანზე გამოჩნდება ან თქვენს მოწყობილობაზე დაიკვრება ჩაწერის ან ტრანსლირების განმავლობაში. აღნიშნული მოიცავს ისეთ ინფორმაციას, როგორიც არის პაროლები, გადახდის დეტალები, ფოტოები, შეტყობინებები და თქვენ მიერ დაკრული აუდიო."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ამ ფუნქციის მომწოდებელ სერვისს ექნება წვდომა ყველა ინფორმაციაზე, რომელიც თქვენს ეკრანზე გამოჩნდება ან თქვენს მოწყობილობაზე დაიკვრება ჩაწერის ან ტრანსლირების განმავლობაში. აღნიშნული მოიცავს ისეთ ინფორმაციას, როგორიც არის პაროლები, გადახდის დეტალები, ფოტოები, შეტყობინებები და თქვენ მიერ დაკრული აუდიო."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"დაიწყოს ჩაწერა ან ტრანსლირება?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"დაიწყოს ჩაწერა ან ტრანსლირება <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ით?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"აღარ მაჩვენო"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ყველას გასუფთავება"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"მართვა"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ჩუმი შეტყობინებები"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"მიმოწერები"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ყველა ჩუმი შეტყობინების გასუფთავება"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"მორგება"</string>
     <string name="notification_done" msgid="6215117625922713976">"მზადაა"</string>
     <string name="inline_undo" msgid="9026953267645116526">"მოქმედების გაუქმება"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"შეტყობინებების მართვის საშუალებები"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"შეტყობინებების ჩაჩუმების ვარიანტები"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index f60aeaf..19ae4e2 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өшірулі"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC қосулы"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Қолданбалар арасында ауысу үшін жоғары сырғытыңыз"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Қолданбаларды жылдам ауыстырып қосу үшін оңға қарай сүйреңіз"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Шолуды қосу/өшіру"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Battery saver функциясын өшіру"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранда көрсетілетін немесе жазу не трансляциялау кезінде құрылғыда ойнатылған барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және ойнатылатын аудио сияқты ақпарат кіреді."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Осы функцияны ұсынатын қызмет экранда көрсетілетін немесе жазу не трансляциялау кезінде құрылғыда ойнатылған барлық ақпаратты пайдалана алады. Бұған құпия сөздер, төлем туралы мәліметтер, суреттер, хабарлар және ойнатылатын аудио сияқты ақпарат кіреді."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жазу немесе трансляциялау басталсын ба?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> арқылы жазу немесе трансляциялау басталсын ба?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Қайта көрсетпеу"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Барлығын тазалау"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Басқару"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Дыбыссыз хабарландырулар"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Сөйлесулер"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Барлық дыбыссыз хабарландыруларды өшіру"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Хабарландырулар \"Мазаламау\" режимінде кідіртілді"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Реттеу"</string>
     <string name="notification_done" msgid="6215117625922713976">"Дайын"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Қайтару"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"хабарландыруларды басқару элементтері"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"хабарландыруды кідірту опциялары"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 0550ade..d6ec177 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"បាន​បិទ NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"បាន​បើក NFC"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"អូស​ឡើង​លើ​ដើម្បី​ប្តូរ​កម្មវិធី"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"អូសទៅស្ដាំដើម្បីប្ដូរកម្មវិធីបានរហ័ស"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"បិទ/បើក​ទិដ្ឋភាពរួម"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"បិទ​កម្មវិធី​សន្សំ​ថ្ម"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹងមានសិទ្ធិ​ចូលប្រើ​ព័ត៌មាន​ទាំងអស់​ដែលអាច​មើលឃើញ​នៅលើ​អេក្រង់​របស់អ្នក ឬដែលចាក់​ពីឧបករណ៍​របស់អ្នក នៅពេល​កំពុង​ថត ឬបញ្ជូន។ ព័ត៌មាន​នេះមាន​ដូចជា ពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិត​អំពីការទូទាត់​ប្រាក់ រូបថត សារ និង​សំឡេង​ដែល​អ្នកចាក់​ជាដើម។"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"សេវាកម្មដែល​ផ្ដល់​មុខងារ​នេះ​នឹងមាន​សិទ្ធិ​ចូលប្រើ​ព័ត៌មាន​ទាំងអស់​ដែល​អាច​មើលឃើញ​នៅលើ​អេក្រង់​របស់អ្នក ឬ​ដែលចាក់​ពីឧបករណ៍​របស់អ្នក នៅពេល​កំពុង​ថត ឬបញ្ជូន។ ព័ត៌មាន​នេះមាន​ដូចជា ពាក្យសម្ងាត់ ព័ត៌មាន​លម្អិត​អំពីការទូទាត់​ប្រាក់ រូបថត សារ និង​សំឡេង​ដែល​អ្នកចាក់​ជាដើម។"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ចាប់ផ្ដើម​ថត ឬបញ្ជូន​មែនទេ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"ចាប់ផ្ដើម​ថត ឬបញ្ជូន​ដោយប្រើ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ឬ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"កុំ​បង្ហាញ​ម្ដងទៀត"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"សម្អាត​ទាំងអស់"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"គ្រប់គ្រង"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ការជូនដំណឹង​ស្ងាត់"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"ការសន្ទនា"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"សម្អាត​ការជូនដំណឹង​ស្ងាត់ទាំងអស់"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើម​ឥឡូវ"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"ប្ដូរតាមបំណង"</string>
     <string name="notification_done" msgid="6215117625922713976">"រួចរាល់"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ត្រឡប់វិញ"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ការគ្រប់គ្រង​ការជូន​ដំណឹង"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ជម្រើស​ផ្អាកការ​ជូនដំណឹង"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 154f13b..fc0f8e6 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಿಸಲು ತ್ವರಿತವಾಗಿ ಬಲಕ್ಕೆ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ಟಾಗಲ್ ನ ಅವಲೋಕನ"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ಬ್ಯಾಟರಿ ಸೇವರ್‌ ಆಫ್ ಮಾಡಿ"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್‌ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ಈ ವೈಶಿಷ್ಟ್ಯವು ಒದಗಿಸುವ ಸೇವೆಗಳು, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್‌ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಬಳಸಿಕೊಂಡು ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸದಿರು"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ನಿರ್ವಹಿಸಿ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳು"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"ಸಂವಾದಗಳು"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ಎಲ್ಲಾ ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಎನ್ನುವ ಮೂಲಕ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"ಕಸ್ಟಮೈಜ್‌ ಮಾಡಿ"</string>
     <string name="notification_done" msgid="6215117625922713976">"ಮುಗಿದಿದೆ"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ರದ್ದುಮಾಡಿ"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ಅಧಿಸೂಚನೆ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
@@ -886,7 +908,7 @@
     <string name="notification_channel_general" msgid="4384774889645929705">"ಸಾಮಾನ್ಯ ಸಂದೇಶಗಳು"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ಸಂಗ್ರಹಣೆ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ಸುಳಿವುಗಳು"</string>
-    <string name="instant_apps" msgid="8337185853050247304">"ತತ್‌ಕ್ಷಣ ಆಪ್‌ಗಳು"</string>
+    <string name="instant_apps" msgid="8337185853050247304">"ಇನ್‌ಸ್ಟಂಟ್ ಆ್ಯಪ್‌ಗಳು"</string>
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡದೆ ಆ್ಯಪ್‌ ತೆರೆಯಲಾಗಿದೆ."</string>
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡದೆ ಆ್ಯಪ್‌ ತೆರೆಯಲಾಗಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index b72a30e..eb3ebc9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 사용 중지됨"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 사용 설정됨"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"위로 스와이프하여 앱 전환"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"앱을 빠르게 전환하려면 오른쪽으로 드래그"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"최근 사용 버튼 전환"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"절전 모드 사용 중지"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>이(가) 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"이 기능을 제공하는 서비스는 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"녹화 또는 전송을 시작하시겠습니까?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>(으)로 녹화 또는 전송을 시작하시겠습니까?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"다시 표시 안함"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"모두 지우기"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"관리"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"무음 알림"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"대화"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"무음 알림 모두 삭제"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 일시중지된 알림"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"맞춤설정"</string>
     <string name="notification_done" msgid="6215117625922713976">"완료"</string>
     <string name="inline_undo" msgid="9026953267645116526">"실행취소"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"알림 관리"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"알림 일시 중지 옵션"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index d2f674f..06f8161 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өчүрүлгөн"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC иштетилген"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Колдонмолорду которуштуруу үчүн өйдө сүрүңүз"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Колдонмолорду тез которуштуруу үчүн оңго сүйрөңүз"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Сереп салууну өчүрүү/күйгүзүү"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Батареяны үнөмдөгүч режимин өчүрүү"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Бул функцияны аткарган <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> кызматы экраныңызда көрүнүп турган бардык маалыматты же жаздыруу жана тышкы экранга чыгаруу учурунда түзмөгүңүздө ойнотулган маалыматты колдоно алат. Буга сырсөздөр, төлөмдүн чоо-жайы, сүрөттөр, билдирүүлөр жана ойнотулган аудио кирет."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Бул функцияны аткарган кызмат экраныңызда көрүнүп турган бардык маалыматты же жаздыруу жана тышкы экранга чыгаруу учурунда түзмөгүңүздө ойнотулган маалыматты колдоно алат. Буга сырсөздөр, төлөмдүн чоо-жайы, сүрөттөр, билдирүүлөр жана ойнотулган аудио кирет."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Жаздырылып же тышкы экранга чыгарылып башталсынбы?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> менен жаздырылып же тышкы экранга чыгарылып башталсынбы?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Экинчи көрсөтүлбөсүн"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Башкаруу"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Үнсүз билдирмелер"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Жазышуулар"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Маанилүү эмес билдирмелердин баарын өчүрүү"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Ыңгайлаштыруу"</string>
     <string name="notification_done" msgid="6215117625922713976">"Бүттү"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Кайтаруу"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"эскертмелерди башкаруу каражаттары"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"эскертмени тындыруу опциялары"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index ca68972..3013e1e 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ປັດຂື້ນເພື່ອສະຫຼັບແອັບ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ລາກໄປຂວາເພື່ອສະຫຼັບແອັບດ່ວນ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ສະຫຼັບພາບຮວມ"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ປິດຕົວປະຢັດແບັດເຕີຣີ"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ຈະມີສິດເຂົ້າເຖິງຂໍ້ມູນທັງໝົດທີ່ປາກົດຢູ່ໜ້າຈໍຂອງທ່ານ ຫຼື ຫຼິ້ນຈາກອຸປະກອນຂອງທ່ານໃນເວລາບັນທຶກ ຫຼື ສົ່ງສັນຍານໜ້າຈໍ. ນີ້ຮວມເຖິງຂໍ້ມູນຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຮູບ, ຂໍ້ຄວາມ ແລະ ສຽງທີ່ທ່ານຫຼິ້ນ."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ບໍລິການທີ່ສະໜອງຄວາມສາມາດນີ້ຈະມີສິດເຂົ້າເຖິງຂໍ້ມູນທັງໝົດທີ່ປາກົດຢູ່ໜ້າຈໍຂອງທ່ານ ຫຼື ຫຼິ້ນຈາກອຸປະກອນຂອງທ່ານໃນເວລາບັນທຶກ ຫຼື ສົ່ງສັນຍານໜ້າຈໍ. ນີ້ຮວມເຖິງຂໍ້ມູນຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຮູບ, ຂໍ້ຄວາມ ແລະ ສຽງທີ່ທ່ານຫຼິ້ນ."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ເລີ່ມການບັນທຶກ ຫຼື ການສົ່ງສັນຍານໜ້າຈໍບໍ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"ເລີ່ມການບັນທຶກ ຫຼື ການສົ່ງສັນຍານໜ້າຈໍກັບ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ບໍ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"ບໍ່​ຕ້ອງ​ສະ​ແດງ​ອີກ"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ຈັດການ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ການແຈ້ງເຕືອນແບບງຽບ"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"ການສົນທະນາ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"ປັບແຕ່ງ"</string>
     <string name="notification_done" msgid="6215117625922713976">"ສຳເລັດແລ້ວ"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ຍົກເລີກ"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ການຄວບຄຸມການແຈ້ງເຕືອນ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ຕົວເລືອກການເລື່ອນການແຈ້ງເຕືອນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 49d678b..c6b50d9 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -395,6 +395,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ALR"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ALR išjungtas"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ALR įjungtas"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekrano įrašas"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Pradėti"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stabdyti"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Perbraukite aukštyn, kad perjungtumėte programas"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Vilkite į dešinę, kad greitai perjungtumėte programas"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Perjungti apžvalgą"</string>
@@ -477,6 +480,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Viską išvalyti"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Tvarkyti"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tylieji pranešimai"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Pokalbiai"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Išvalyti visus tylius pranešimus"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
@@ -695,6 +699,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Tinkinti"</string>
     <string name="notification_done" msgid="6215117625922713976">"Atlikta"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Anuliuoti"</string>
+    <string name="demote" msgid="6225813324237153980">"Žymėti šį pranešimą kaip ne pokalbį"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Mėgstamiausi"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Pašalinti iš mėgstamiausių"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Nutildyti"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Rodyti"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Rodyti kaip debesėlį"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Išjungti debesėlius"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Pridėti prie pagrindinio ekrano"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"pranešimų valdikliai"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"pranešimų snaudimo parinktys"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 1973192..b519f05 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -393,6 +393,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ir atspējoti"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ir iespējoti"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Velciet augšup, lai pārslēgtu lietotnes"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Lai ātri pārslēgtu lietotnes, velciet pa labi"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Pārskata pārslēgšana"</string>
@@ -468,13 +474,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Izslēgt akumulatora jaudas taupīšanas režīmu"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> iegūs piekļuvi visai informācijai, kas ierakstīšanas vai apraides laikā tiks rādīta jūsu ekrānā vai atskaņota jūsu ierīcē. Atļauja attiecas uz tādu informāciju kā paroles, maksājumu informācija, fotoattēli, ziņojumi un jūsu atskaņotais audio saturs."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Pakalpojums, kas nodrošina šo funkciju, iegūs piekļuvi visai informācijai, kas ierakstīšanas vai apraides laikā tiks rādīta jūsu ekrānā vai atskaņota jūsu ierīcē. Atļauja attiecas uz tādu informāciju kā paroles, maksājumu informācija, fotoattēli, ziņojumi un jūsu atskaņotais audio saturs."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Vai vēlaties sākt ierakstīšanu/apraidi?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Vai vēlaties sākt ierakstīšanu vai apraidi, izmantojot lietotni <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Vairs nerādīt"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Dzēst visu"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Pārvaldīt"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Klusie paziņojumi"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Sarunas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Notīrīt visus klusos paziņojumus"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
@@ -693,6 +699,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Pielāgot"</string>
     <string name="notification_done" msgid="6215117625922713976">"Gatavs"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Atsaukt"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"paziņojumu vadīklas"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"paziņojumu atlikšanas opcijas"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 0294a1f..9080b57 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е оневозможено"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е овозможено"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Снимање екран"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Започни"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Сопри"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Повлечете нагоре за да се префрлите од една на друга апликација"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Повлечете надесно за брзо префрлање меѓу апликациите"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Вклучи/исклучи преглед"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Избриши сѐ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Управувајте"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Тивки известувања"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Исчисти ги сите тивки известувања"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известувањата се паузирани од „Не вознемирувај“"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Приспособете"</string>
     <string name="notification_done" msgid="6215117625922713976">"Готово"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Врати"</string>
+    <string name="demote" msgid="6225813324237153980">"Означи го известувањево како „не е разговор“"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Омилен"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Неомилен"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Исклучи звук"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Вклучи звук"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Прикажи како балонче"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Исклучи балончиња"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Додај на почетниот екран"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"контроли за известувањето"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"опции за одложување на известувањето"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index a830313..b761c44 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC പ്രവർത്തനക്ഷമമാക്കി"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ആപ്പുകൾ മാറാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ആപ്പുകൾ പെട്ടെന്ന് മാറാൻ വലത്തോട്ട് വലിച്ചിടുക"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"അവലോകനം മാറ്റുക"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ബാറ്ററി ലാഭിക്കൽ ഓഫാക്കുക"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്‌റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്‌ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ആക്‌സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഒഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, പാസ്‌വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"റെക്കോർഡ് ചെയ്യുമ്പോഴോ കാസ്‌റ്റ് ചെയ്യുമ്പോഴോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്യുന്നതോ നിങ്ങളുടെ സ്‌ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആയ എല്ലാ വിവരങ്ങളിലേക്കും ഈ ഫംഗ്‌ഷൻ ലഭ്യമാക്കുന്ന സേവനത്തിന് ആക്‌സസ് ഉണ്ടായിരിക്കും. നിങ്ങൾ പ്ലേ ചെയ്യുന്ന ഒഡിയോ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, പാസ്‌വേഡുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"റെക്കോർഡ് ചെയ്യൽ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യൽ ആരംഭിക്കണോ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ഉപയോഗിച്ച് റെക്കോർഡ് ചെയ്യൽ അല്ലെങ്കിൽ കാസ്‌റ്റ് ചെയ്യൽ ആരംഭിക്കണോ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"വീണ്ടും കാണിക്കരുത്"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"മാനേജ് ചെയ്യുക"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"നിശബ്‌ദ അറിയിപ്പുകൾ"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"സംഭാഷണങ്ങൾ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"എല്ലാ നിശബ്‌ദ അറിയിപ്പുകളും മായ്ക്കുക"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
     <string name="notification_done" msgid="6215117625922713976">"പൂർത്തിയായി"</string>
     <string name="inline_undo" msgid="9026953267645116526">"പഴയപടിയാക്കുക"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"അറിയിപ്പ് നിയന്ത്രണങ്ങൾ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"അറിയിപ്പ് സ്‌നൂസ് ഓപ്ഷനുകൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index e5497ea..4f9b447 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-г цуцалсан"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-г идэвхжүүлсэн"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Апп сэлгэхийн тулд дээш шударна уу"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Аппуудыг хурдан сэлгэхийн тулд баруун тийш чирнэ үү"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Тоймыг унтраах/асаах"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Бүгдийг арилгах"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Удирдах"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Чимээгүй мэдэгдэл"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Харилцан яриа"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бүх чимээгүй мэдэгдлийг арилгах"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Тохируулах"</string>
     <string name="notification_done" msgid="6215117625922713976">"Дууссан"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Болих"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"мэдэгдлийн удирдлага"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"мэдэгдэл түр хойшлуулагчийн сонголт"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 3eb74b7..99f48e6 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC अक्षम केले आहे"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC सक्षम केले आहे"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"अ‍ॅप्स स्विच करण्यासाठी वर स्वाइप करा"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"अ‍ॅप्स वर झटपट स्विच करण्यासाठी उजवीकडे ड्रॅग करा"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"अवलोकन टॉगल करा."</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"बॅटरी सेव्हर बंद करा"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"तुमच्या स्क्रीनवर दृश्यमान असलेल्या किंवा रेकॉर्ड किंवा कास्ट करताना तुमच्या डिव्हाइसमधून प्ले केलेल्या सर्व माहितीचा अ‍ॅक्सेस <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला असेल. यामध्ये पासवर्ड, पेमेंट तपशील, फोटो, मेसेज आणि तुम्ही प्ले केलेला ऑडिओ यासारख्या माहितीचा समावेश असतो."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"हे कार्य पुरवठा करणाऱ्या सेवेस तुमच्या स्क्रीनवर दृश्यमान असलेल्या किंवा रेकॉर्ड किंवा कास्ट करताना तुमच्या डिव्हाइसमधून प्ले केलेल्या सर्व माहितीचा अ‍ॅक्सेस असेल. यामध्ये पासवर्ड, पेमेंट तपशील, फोटो, मेसेज आणि तुम्ही प्ले केलेला ऑडिओ यासारख्या माहितीचा समावेश असतो."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"रेकॉर्ड किंवा कास्ट करणे सुरू करायचे आहे का ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ने रेकॉर्ड करणे किंवा कास्ट करणे सुरू करा?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"पुन्हा दर्शवू नका"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"सर्व साफ करा"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थापित करा"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"सायलंट सूचना"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"संभाषणे"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सर्व सायलंट सूचना साफ करा"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"कस्टमाइझ करा"</string>
     <string name="notification_done" msgid="6215117625922713976">"पूर्ण झाले"</string>
     <string name="inline_undo" msgid="9026953267645116526">"पहिल्यासारखे करा"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"सूचना नियंत्रणे"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"सूचना स्नूझ पर्याय"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index b632bcd..42c51b7 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dilumpuhkan"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC didayakan"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Leret ke atas untuk menukar apl"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Seret ke kanan untuk beralih apl dengan pantas"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Togol Ikhtisar"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Kosongkan semua"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Urus"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Pemberitahuan senyap"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kosongkan semua pemberitahuan senyap"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Sesuaikan"</string>
     <string name="notification_done" msgid="6215117625922713976">"Selesai"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Buat asal"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kawalan pemberitahuan"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"pilihan tunda pemberitahuan"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 45893c1..dd5acfa 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ကို ပိတ်ထားသည်"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ကို ဖွင့်ထားသည်"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"အက်ပ်များကို ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"အက်ပ်များကို ပြောင်းရန် ညာဘက်သို့ ဖိဆွဲပါ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ဖွင့်၊ ပိတ် အနှစ်ချုပ်"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ဘက်ထရီ အားထိန်းကို ပိတ်ရန်"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်မျက်နှာပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ဤလုပ်ဆောင်ချက်ကို ပေးအပ်သည့် ဝန်ဆောင်မှုသည် အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် သင့်မျက်နှာပြင်တွင် မြင်ရသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အချက်အလက်မှန်သမျှကို သုံးနိုင်ပါမည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှုအသေးစိတ်များ၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် သင်ဖွင့်သည့်အသံကဲ့သို့သော အချက်အလက်များ ပါဝင်သည်။"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ဖမ်းယူခြင်း သို့မဟုတ် ကာစ်လုပ်ခြင်း စတင်မလား။"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> နှင့် ဖမ်းယူခြင်း သို့မဟုတ် ကာစ်လုပ်ခြင်း စတင်မလား။"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"နောက်ထပ် မပြပါနှင့်"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"အားလုံး ဖယ်ရှားရန်"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"စီမံရန်"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"အကြောင်းကြားချက်များကို အသံတိတ်ခြင်း"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"စကားဝိုင်းများ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"အသံတိတ် အကြောင်းကြားချက်များအားလုံးကို ရှင်းလင်းရန်"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"စိတ်ကြိုက်ပြုလုပ်ရန်"</string>
     <string name="notification_done" msgid="6215117625922713976">"ပြီးပါပြီ"</string>
     <string name="inline_undo" msgid="9026953267645116526">"တစ်ဆင့်နောက်ပြန်ရန်"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"အကြောင်းကြားချက် ထိန်းချုပ်မှုများ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"အကြောင်းကြားချက်များကို ဆိုင်းငံ့ရန် ရွေးချယ်စရာများ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index d07bd8e..97d6792 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er slått av"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er slått på"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Sveip opp for å bytte apper"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Dra til høyre for å bytte apper raskt"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Slå oversikten av eller på"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Slå av batterisparing"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> får tilgang til all informasjon som er synlig på skjermen din, eller som spilles av fra enheten når du tar opp eller caster. Dette inkluderer informasjon som passord, betalingsopplysninger, bilder, meldinger og lyd du spiller av."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Tjenesten som leverer denne funksjonen, får tilgang til all informasjon som er synlig på skjermen din, eller som spilles av fra enheten når du tar opp eller caster. Dette inkluderer informasjon som passord, betalingsopplysninger, bilder, meldinger og lyd du spiller av."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Vil du starte opptak eller casting?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Vil du starte opptak eller casting med <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Ikke vis igjen"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Lydløse varsler"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Fjern alle lydløse varsler"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Varsler er satt på pause av «Ikke forstyrr»"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Tilpass"</string>
     <string name="notification_done" msgid="6215117625922713976">"Ferdig"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Angre"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"varselinnstillinger"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"slumrealternativer for varsler"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ba6b0ed..1345b09 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC लाई असक्षम पारिएको छ"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC लाई सक्षम पारिएको छ"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"अनुप्रयोगहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"अनुप्रयोगहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"परिदृश्य टगल गर्नुहोस्"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"सबै हटाउनुहोस्"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थित गर्नुहोस्"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"मौन सूचनाहरू"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"अहिले सुरु गर्नुहोस्"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"आफू अनुकूल पार्नुहोस्"</string>
     <string name="notification_done" msgid="6215117625922713976">"सम्पन्‍न भयो"</string>
     <string name="inline_undo" msgid="9026953267645116526">"अन्डू गर्नुहोस्"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"सूचना सम्बन्धी नियन्त्रणहरू"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"सूचना स्नुज गर्ने विकल्पहरू"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 638fcad..71d2388 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is uitgeschakeld"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is ingeschakeld"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Schermopname"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starten"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stoppen"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Veeg omhoog om te schakelen tussen apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Sleep naar rechts om snel tussen apps te schakelen"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Overzicht in-/uitschakelen"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Alles wissen"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Beheren"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Stille meldingen"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekken"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle stille meldingen wissen"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Meldingen onderbroken door \'Niet storen\'"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Aanpassen"</string>
     <string name="notification_done" msgid="6215117625922713976">"Gereed"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Ongedaan maken"</string>
+    <string name="demote" msgid="6225813324237153980">"Deze melding markeren als geen gesprek"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Markeren als favoriet"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Favoriet verwijderen"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Negeren"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Negeren opheffen"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Weergeven als ballon"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Ballonnen uitschakelen"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Toevoegen aan startscherm"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"beheeropties voor meldingen"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"snooze-opties voor meldingen"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 7586be5..85841fe 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ଆପ୍‌କୁ ବଦଳ କରିବା ପାଇଁ ସ୍ଵାଇପ୍ କରନ୍ତୁ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ଆପ୍‌ଗୁଡ଼ିକ ମଧ୍ୟରେ ଶୀଘ୍ର ବଦଳ କରିବା ପାଇଁ ଡାହାଣକୁ ଡ୍ରାଗ୍ କରନ୍ତୁ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀକୁ ଟୋଗଲ୍ କରନ୍ତୁ"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅଫ୍‍ କରନ୍ତୁ"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ରେ ସମସ୍ତ ସୂଚନାକୁ ଆକ୍ସେସ୍ ରହିବ ଯାହା ଆପଣଙ୍କର ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯିବ ବା ରେକର୍ଡିଂ ବା କାଷ୍ଟିଂ ବେଳେ ଆପଣଙ୍କର ଡିଭାଇସ୍ ଠାରୁ ଚାଲିବ। ପାସ୍‌ୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ଫଟୋ, ମେସେଜ୍ ଏବଂ ଆପଣ ଚଲାଉଥିବା ଅଡିଓ ପରି ସୂଚନା ଅନ୍ତର୍ଭୁକ୍ତ ଅଛି।"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ଏହି ପ୍ରକାର୍ଯ୍ୟ ପ୍ରଦାନ କରୁଥିବା ସେବା ସମସ୍ତ ସୂଚନାକୁ ଆକ୍ସେସ୍ ରହିବ ଯାହା ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯିବ ବା ରେକର୍ଡିଂ ବା କାଷ୍ଟିଂ ବେଳେ ଆପଣଙ୍କର ଡିଭାଇସ୍ ଠାରୁ ଚାଲିବ। ପାସ୍‌ୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ଫଟୋ, ମେସେଜ୍ ଏବଂ ଆପଣ ଚଲାଉଥିବା ଅଡିଓ ପରି ସୂଚନା ଅନ୍ତର୍ଭୁକ୍ତ ଅଛି।"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ରେକର୍ଡିଂ ବା କାଷ୍ଟିଂ ଆରମ୍ଭ କରିବେ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ସହ ରେକର୍ଡିଂ ବା କାଷ୍ଟିଂ ଆରମ୍ଭ କରିବେ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ସମସ୍ତ ଖାଲି କରନ୍ତୁ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"କଷ୍ଟମାଇଜ୍‌ କରନ୍ତୁ"</string>
     <string name="notification_done" msgid="6215117625922713976">"ହୋଇଗଲା"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ପୂର୍ବସ୍ଥାନକୁ ଫେରାଇଆଣନ୍ତୁ"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ବିଜ୍ଞପ୍ତି ସ୍ନୁଜ୍‍ ବିକଳ୍ପ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6e1f230..4ea51dd 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ਨੂੰ ਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ਐਪਾਂ ਵਿਚਾਲੇ ਤੇਜ਼ੀ ਨਾਲ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਘਸੀਟੋ"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"ਰੂਪ-ਰੇਖਾ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ਬੈਟਰੀ ਸੇਵਰ ਬੰਦ ਕਰੋ"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਕੋਲ ਬਾਕੀ ਸਾਰੀ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ ਜੋ ਕਿ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਣਯੋਗ ਹੈ ਜਾਂ ਰਿਕਾਰਡਿੰਗ ਜਾਂ ਕਾਸਟ ਕਰਨ ਵੇਲੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਂਦੀ ਹੈ। ਇਸ ਵਿੱਚ ਪਾਸਵਰਡ, ਭੁਗਤਾਨ ਵੇਰਵੇ, ਫ਼ੋਟੋਆਂ, ਸੁਨੇਹੇ ਅਤੇ ਤੁਹਾਡੇ ਵੱਲੋਂ ਚਲਾਏ ਆਡੀਓ ਦੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ।"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ਇਸ ਫੰਕਸ਼ਨ ਦੇ ਸੇਵਾ ਪ੍ਰਦਾਨਕ ਕੋਲ ਬਾਕੀ ਸਾਰੀ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ ਜੋ ਕਿ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਣਯੋਗ ਹੁੰਦੀ ਹੈ ਜਾਂ ਰਿਕਾਰਡਿੰਗ ਜਾਂ ਕਾਸਟ ਕਰਨ ਵੇਲੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਂਦੀ ਹੈ। ਇਸ ਵਿੱਚ ਪਾਸਵਰਡ, ਭੁਗਤਾਨ ਵੇਰਵੇ, ਫ਼ੋਟੋਆਂ, ਸੁਨੇਹੇ ਅਤੇ ਤੁਹਾਡੇ ਵੱਲੋਂ ਚਲਾਏ ਆਡੀਓ ਦੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ।"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ਕੀ ਰਿਕਾਰਡਿੰਗ ਜਾਂ ਕਾਸਟ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਨਾਲ ਰਿਕਾਰਡਿੰਗ ਜਾਂ ਕਾਸਟ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣ ਚਾਲੂ ਕਰੋ"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
     <string name="notification_done" msgid="6215117625922713976">"ਹੋ ਗਿਆ"</string>
     <string name="inline_undo" msgid="9026953267645116526">"ਅਣਕੀਤਾ ਕਰੋ"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ਸੂਚਨਾ ਸਨੂਜ਼ ਵਿਕਲਪ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 307d417..515d659 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -395,6 +395,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Komunikacja NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Komunikacja NFC jest wyłączona"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Komunikacja NFC jest włączona"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Przesuń w górę, by przełączyć aplikacje"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Szybko przeciągnij w prawo, by przełączyć aplikacje"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Przełącz Przegląd"</string>
@@ -477,6 +483,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Usuń wszystkie"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Zarządzaj"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Ciche powiadomienia"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Rozmowy"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Usuń wszystkie ciche powiadomienia"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
@@ -695,6 +702,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Dostosuj"</string>
     <string name="notification_done" msgid="6215117625922713976">"Gotowe"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Cofnij"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"sterowanie powiadomieniami"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opcje odkładania powiadomień"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index c1dd243..d486b9b 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravação de tela"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Parar"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Deslize para cima para alternar entre os apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arraste para a direita para alternar rapidamente entre os apps"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Alternar Visão geral"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificações silenciosas"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string>
     <string name="notification_done" msgid="6215117625922713976">"Concluído"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Desfazer"</string>
+    <string name="demote" msgid="6225813324237153980">"Marcar esta notificação como não sendo uma conversa"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Adicionar como favorito"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Remover dos favoritos"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Desativar som"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Ativar som"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostrar como balão"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desativar balões"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Adicionar à tela inicial"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"controles de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opções de adiamento de notificação"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 9a5a4b3..d17b002 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"O NFC está desativado"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"O NFC está ativado"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravação de ecrã"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Parar"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Deslizar rapidamente para cima para mudar de aplicação"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arraste para a direita para mudar rapidamente de aplicação."</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Ativar/desativar Vista geral"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gerir"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificações silenciosas"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Limpar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
@@ -557,7 +561,7 @@
     <string name="screen_pinning_toast" msgid="2083944237147005811">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Vista geral."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="6343770487795352573">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Página inicial."</string>
     <string name="screen_pinning_toast_gesture_nav" msgid="2884536903398445645">"Para soltar este ecrã, deslize rapidamente para cima sem soltar."</string>
-    <string name="screen_pinning_positive" msgid="3285785989665266984">"Compreendi"</string>
+    <string name="screen_pinning_positive" msgid="3285785989665266984">"OK"</string>
     <string name="screen_pinning_negative" msgid="6882816864569211666">"Não, obrigado"</string>
     <string name="screen_pinning_start" msgid="5695091877402422575">"Ecrã fixo"</string>
     <string name="screen_pinning_exit" msgid="5114993350662745840">"Ecrã solto"</string>
@@ -621,7 +625,7 @@
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string>
-    <string name="got_it" msgid="477119182261892069">"Compreendi"</string>
+    <string name="got_it" msgid="477119182261892069">"OK"</string>
     <string name="tuner_toast" msgid="3812684836514766951">"Parabéns! O Sintonizador da interface do sistema foi adicionado às Definições"</string>
     <string name="remove_from_settings" msgid="633775561782209994">"Remover das Definições"</string>
     <string name="remove_from_settings_prompt" msgid="551565437265615426">"Pretende remover o Sintonizador da interface do sistema das Definições e deixar de utilizar todas as respetivas funcionalidades?"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string>
     <string name="notification_done" msgid="6215117625922713976">"Concluído"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Anular"</string>
+    <string name="demote" msgid="6225813324237153980">"Marcar esta notificação como não sendo uma conversa"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Adicionar aos favoritos"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Remover dos favoritos"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Ignorar"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Ativar"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostrar como balão"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desativar balões"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Adicionar ao ecrã principal"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"controlos de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opções de suspensão de notificações"</string>
@@ -921,7 +933,7 @@
     <string name="auto_saver_enabled_title" msgid="4294726198280286333">"Poupança de bateria agendada ativada"</string>
     <string name="auto_saver_enabled_text" msgid="7889491183116752719">"A Poupança de bateria é ativada automaticamente quando o nível de bateria está abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="open_saver_setting_action" msgid="2111461909782935190">"Definições"</string>
-    <string name="auto_saver_okay_action" msgid="7815925750741935386">"Compreendi"</string>
+    <string name="auto_saver_okay_action" msgid="7815925750741935386">"OK"</string>
     <string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar pilha SysUI"</string>
     <string name="sensor_privacy_mode" msgid="4462866919026513692">"Sensores desativados"</string>
     <string name="device_services" msgid="1549944177856658705">"Serviços do dispositivo"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c1dd243..d486b9b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravação de tela"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Parar"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Deslize para cima para alternar entre os apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arraste para a direita para alternar rapidamente entre os apps"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Alternar Visão geral"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificações silenciosas"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string>
     <string name="notification_done" msgid="6215117625922713976">"Concluído"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Desfazer"</string>
+    <string name="demote" msgid="6225813324237153980">"Marcar esta notificação como não sendo uma conversa"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Adicionar como favorito"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Remover dos favoritos"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Desativar som"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Ativar som"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Mostrar como balão"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Desativar balões"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Adicionar à tela inicial"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g> do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"controles de notificação"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opções de adiamento de notificação"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 63c2c0a..2674504 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -393,6 +393,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Serviciul NFC este dezactivat"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Serviciul NFC este activat"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Glisați în sus pentru a comuta între aplicații"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Glisați la dreapta pentru a comuta rapid între aplicații"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Comutați secțiunea Recente"</string>
@@ -468,13 +474,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Dezactivați economisirea bateriei"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va avea acces la toate informațiile vizibile pe ecran sau redate pe dispozitiv în timp ce înregistrați sau proiectați. Între aceste informații se numără parole, detalii de plată, fotografii, mesaje și conținutul audio pe care îl redați."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Serviciul care oferă această funcție va avea acces la toate informațiile vizibile pe ecran sau redate pe dispozitiv în timp ce înregistrați sau proiectați. Între aceste informații se numără parole, detalii de plată, fotografii, mesaje și conținutul audio pe care îl redați."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Începeți să înregistrați sau să proiectați?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Începeți să înregistrați sau să proiectați cu <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Nu se mai afișează"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Ștergeți toate notificările"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestionați"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificări silențioase"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversații"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ștergeți toate notificările silențioase"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificări întrerupte prin „Nu deranja”"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Începeți acum"</string>
@@ -693,6 +699,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizați"</string>
     <string name="notification_done" msgid="6215117625922713976">"Terminat"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Anulați"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"comenzile notificării"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opțiuni de amânare a notificării"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 2da136f..9156989 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -395,6 +395,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Модуль NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Модуль NFC отключен"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Модуль NFC включен"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Чтобы переключиться между приложениями, проведите по экрану вверх."</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Перетащите вправо, чтобы быстро переключиться между приложениями"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Переключить режим обзора"</string>
@@ -471,13 +477,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Отключить режим энергосбережения"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Во время записи или трансляции у приложения \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" будет доступ ко всей информации, которая видна на экране или воспроизводится с устройства, в том числе к паролям, сведениям о платежах, фотографиям, сообщениям и прослушиваемым аудиозаписям."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Во время записи или трансляции у сервиса, предоставляющего эту функцию, будет доступ ко всей информации, которая видна на экране или воспроизводится с устройства, в том числе к паролям, сведениям о платежах, фотографиям, сообщениям и прослушиваемым аудиозаписям."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Начать запись или трансляцию?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Начать запись или трансляцию через приложение \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\"?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Больше не показывать"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Очистить все"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Настроить"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Беззвучные уведомления"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Чаты"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Отклонить все беззвучные уведомления"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"В режиме \"Не беспокоить\" уведомления заблокированы"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
@@ -696,6 +702,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Настроить"</string>
     <string name="notification_done" msgid="6215117625922713976">"Готово"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Отменить"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g>: <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"настройки уведомлений"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"параметры отсрочки уведомлений"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 94a7448..84e01d0 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC අබලයි"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC සබලයි"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"යෙදුම් මාරු කිරීමට ස්වයිප් කරන්න"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ඉක්මනින් යෙදුම් මාරු කිරීමට දකුණට අදින්න"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"දළ විශ්ලේෂණය ටොගල කරන්න"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"බැටරි සුරැකුම ක්‍රියාවිරහිත කරන්න"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ට පටිගත කරන හෝ විකාශ කරන අතරතුර ඔබේ තිරයේ දිස් වන හෝ ඔබේ උපාංගයෙන් වාදනය කරන සියලු තොරතුරු වෙත ප්‍රවේශ ලැබෙනු ඇත. මෙහි මුරපද, ගෙවීම් විස්තර, ඡායාරූප, පණිවිඩ සහ ඔබ වාදනය කරන ඕඩියෝ යනාදි තොරතුරු ඇතුළත් වේ."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"මෙම ශ්‍රිතය සපයන සේවාවට පටිගත කරන හෝ විකාශ කරන අතරතුර ඔබේ තිරයේ දිස් වන හෝ ඔබේ උපාංගයෙන් වාදනය කරන සියලු තොරතුරු වෙත ප්‍රවේශය ලැබෙනු ඇත. මෙහි මුරපද, ගෙවීම් විස්තර, ඡායාරූප, පණිවිඩ සහ ඔබ වාදනය කරන ඕඩියෝ යනාදි තොරතුරු ඇතුළත් වේ."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"පටිගත කිරීම හෝ විකාශය කිරීම ආරම්භ කරන්නද?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> සමග පටිගත කිරීම හෝ විකාශය කිරීම ආරම්භ කරන්නද?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"නැවත නොපෙන්වන්න"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"සියල්ල හිස් කරන්න"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"කළමනාකරණය කරන්න"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"නිහඬ දැනුම්දීම්"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"සංවාද"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"සියලු නිහඬ දැනුම්දීම් හිස් කරන්න"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"බාධා නොකරන්න මගින් විරාම කරන ලද දැනුම්දීම්"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"අභිරුචිකරණය"</string>
     <string name="notification_done" msgid="6215117625922713976">"නිමයි"</string>
     <string name="inline_undo" msgid="9026953267645116526">"පසුගමනය කරන්න"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"දැනුම්දීම් පාලන"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"දැනුම්දීම් මදක් නතර කිරීමේ විකල්ප"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c38c855..fced8a4 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -395,6 +395,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je deaktivované"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je aktivované"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Záznam obrazovky"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Začať"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ukončiť"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Potiahnutím nahor prepnete aplikácie"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Presunutím doprava rýchlo prepnete aplikácie"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Prepnúť prehľad"</string>
@@ -477,6 +480,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Vymazať všetko"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Spravovať"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tiché upozornenia"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazať všetky tiché upozornenia"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
@@ -695,6 +699,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Prispôsobiť"</string>
     <string name="notification_done" msgid="6215117625922713976">"Hotovo"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Späť"</string>
+    <string name="demote" msgid="6225813324237153980">"Označiť, že toto upozornenie nie je konverzácia"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Obľúbená"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Odstrániť z obľúbených"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Vypnúť zvuk"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Zapnúť zvuk"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Zobraziť ako bublinu"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Vypnúť bubliny"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Pridať na plochu"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ovládacie prvky pre upozornenia"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"možnosti stlmenia upozornení"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2c8893e..4816a66 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -395,6 +395,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Tehnologija NFC je onemogočena"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Tehnologija NFC je omogočena"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Za preklop aplikacij povlecite navzgor"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Povlecite v desno za hiter preklop med aplikacijami"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Vklop/izklop pregleda"</string>
@@ -471,13 +477,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Izklop varčevanja z energijo akumulatorja"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bo imela dostop do vseh podatkov, ki so med snemanjem ali predvajanjem prikazani na vašem zaslonu ali se predvajajo iz vaše naprave. To vključuje podatke, kot so gesla, podrobnosti o plačilu, fotografije, sporočila in zvok, ki ga predvajate."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Storitev, ki zagotavlja to funkcijo, bo imela dostop do vseh podatkov, ki so med snemanjem ali predvajanjem prikazani na vašem zaslonu ali se predvajajo iz vaše naprave. To vključuje podatke, kot so gesla, podrobnosti o plačilu, fotografije, sporočila in zvok, ki ga predvajate."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Želite začeti snemati ali predvajati?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Želite začeti snemati ali predvajati z aplikacijo <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Tega ne prikaži več"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši vse"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljanje"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tiha obvestila"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Pogovori"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Brisanje vseh tihih obvestil"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
@@ -696,6 +702,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Prilagodi"</string>
     <string name="notification_done" msgid="6215117625922713976">"Dokončano"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Razveljavi"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrolniki obvestil"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"možnosti preložitve obvestil"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 445f8ca4..14d72b4 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC është çaktivizuar"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC është aktivizuar"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Rrëshqit shpejt lart për të ndërruar aplikacionet"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Zvarrit djathtas për të ndërruar aplikacionet me shpejtësi"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Kalo te përmbledhja"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Pastroji të gjitha"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Menaxho"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Njoftimet në heshtje"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Bisedat"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Pastro të gjitha njoftimet në heshtje"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Personalizo"</string>
     <string name="notification_done" msgid="6215117625922713976">"U krye"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Zhbëj"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"kontrollet e njoftimit"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"opsionet e shtyrjes së njoftimit"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index acff269..29e7e10 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -393,6 +393,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC је онемогућен"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC је омогућен"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Снимак екрана"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Почните"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зауставите"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Превуците нагоре да бисте мењали апликације"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Превуците удесно да бисте брзо променили апликације"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Укључи/искључи преглед"</string>
@@ -474,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Обриши све"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Управљајте"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Нечујна обавештења"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Обришите сва нечујна обавештења"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни одмах"</string>
@@ -692,6 +696,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Прилагоди"</string>
     <string name="notification_done" msgid="6215117625922713976">"Готово"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Опозови"</string>
+    <string name="demote" msgid="6225813324237153980">"Означи да ово обавештење није конверзација"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Означи као омиљено"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Уклони из омиљених"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Искључи звук"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Укључи звук"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Прикажи као облачић"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Искључи облачиће"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Додај на почетни екран"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"контроле обавештења"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"опције за одлагање обавештења"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index d63206a..b0d7877 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC är inaktiverat"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC är aktiverat"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Skärminspelning"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starta"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stoppa"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Byt appar genom att svepa uppåt"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tryck och dra åt höger för att snabbt byta mellan appar"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Aktivera och inaktivera översikten"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Rensa alla"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Hantera"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Ljudlösa aviseringar"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Rensa alla ljudlösa aviseringar"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Aviseringar har pausats via Stör ej"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Anpassa"</string>
     <string name="notification_done" msgid="6215117625922713976">"Klar"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Ångra"</string>
+    <string name="demote" msgid="6225813324237153980">"Markera aviseringen som icke-konversation"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Favorit"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Ta bort från favoriter"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Dölj"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Visa"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Visa som bubbla"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Inaktivera bubblor"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Lägg till på startskärmen"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"inställningar för aviseringar"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"alternativ för att snooza aviseringar"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9f319a6..ecaefb0 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC imezimwa"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC imewashwa"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Telezesha kidole juu ili ubadilishe programu"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Buruta kulia ili ubadilishe programu haraka"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Washa Muhtasari"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Zima Kiokoa Betri"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> itaweza kufikia maelezo yote yanayoonekana kwenye skrini yako au yanayochezwa kwenye kifaa chako wakati wa kurekodi au kutuma. Hii ni pamoja na maelezo kama vile manenosiri, maelezo ya malipo, picha, ujumbe na sauti unayocheza."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Huduma inayotoa utendaji huu itaweza kufikia maelezo yote yanayoonekana kwenye skrini yako au yanayochezwa kwenye kifaa chako wakati wa kurekodi au kutuma. Hii ni pamoja na maelezo kama vile manenosiri, maelezo ya malipo, picha, ujumbe na sauti unayocheza."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Ungependa kuanza kurekodi au kutuma?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Ungependa kuanza kurekodi au kutuma ukitumia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Usionyeshe tena"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Futa zote"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Dhibiti"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Arifa zisizo na sauti"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Mazungumzo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Futa arifa zote zisizo na sauti"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Weka mapendeleo"</string>
     <string name="notification_done" msgid="6215117625922713976">"Nimemaliza"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Tendua"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"vidhibiti vya arifa"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"chaguo za kuahirisha arifa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index d4c3c05..0bea7d6 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC முடக்கப்பட்டது"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC இயக்கப்பட்டது"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ஆப்ஸிற்கு இடையே மாற்றுவதற்கு, மேல்நோக்கி ஸ்வைப் செய்க"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ஆப்ஸை வேகமாக மாற்ற, வலப்புறம் இழுக்கவும்"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"மேலோட்டப் பார்வையை நிலைமாற்று"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"பேட்டரி சேமிப்பானை ஆஃப் செய்"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> உங்கள் திரையில் தெரியும் தகவல்கள், ரெக்கார்டு செய்யும்போதோ அனுப்பும்போதோ உங்கள் சாதனத்திலிருந்து பிளே ஆகும் அனைத்து தகவல்கள் ஆகியவற்றுக்கான அணுகலைக் கொண்டிருக்கும். கடவுச்சொற்கள், பேமெண்ட் தொடர்பான தகவல்கள், படங்கள், மெசேஜ்கள், நீங்கள் பிளே செய்யும் ஆடியோ போன்ற அனைத்துத் தகவல்களும் இதில் அடங்கும்."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"இந்தச் செயல்பாட்டை வழங்கும் சேவையானது உங்கள் திரையில் தெரியும் தகவல்கள், ரெக்கார்டு செய்யும்போதோ அனுப்பும்போதோ உங்கள் சாதனத்திலிருந்து பிளே ஆகும் அனைத்துத் தகவல்கள் ஆகியவற்றுக்கான அணுகலைக் கொண்டிருக்கும். கடவுச்சொற்கள், பேமெண்ட் தொடர்பான தகவல்கள், படங்கள், மெசேஜ்கள், நீங்கள் பிளே செய்யும் ஆடியோ போன்ற அனைத்துத் தகவல்களும் இதில் அடங்கும்."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ரெக்கார்டிங் செய்யவோ அனுப்புவதற்கோ தொடங்கிவிட்டீர்களா?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> மூலம் ரெக்கார்டிங் செய்யவோ அனுப்புவதற்கோ தொடங்கிவீட்டீர்களா?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"மீண்டும் காட்டாதே"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"எல்லாவற்றையும் அழி"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"அறிவிப்புகளை நிர்வகி"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ஒலியில்லாத அறிவிப்புகள்"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"உரையாடல்கள்"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ஒலியில்லாத அழைப்புகள் அனைத்தையும் அழிக்கும்"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"தனிப்பயனாக்கு"</string>
     <string name="notification_done" msgid="6215117625922713976">"முடிந்தது"</string>
     <string name="inline_undo" msgid="9026953267645116526">"செயல்தவிர்"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"அறிவிப்புக் கட்டுப்பாடுகள்"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"அறிவிப்பை உறக்கநிலையாக்கும் விருப்பங்கள்"</string>
@@ -946,10 +968,7 @@
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"இயக்க நேரம்"</string>
-    <!-- no translation found for magnification_overlay_title (6584179429612427958) -->
-    <skip />
-    <!-- no translation found for magnification_window_title (4863914360847258333) -->
-    <skip />
-    <!-- no translation found for magnification_controls_title (8421106606708891519) -->
-    <skip />
+    <string name="magnification_overlay_title" msgid="6584179429612427958">"Magnification Overlay Window"</string>
+    <string name="magnification_window_title" msgid="4863914360847258333">"பெரிதாக்கல் சாளரம்"</string>
+    <string name="magnification_controls_title" msgid="8421106606708891519">"பெரிதாக்கல் சாளரக் கட்டுப்பாடுகள்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 1baf89c..bb62490 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC నిలిపివేయబడింది"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ప్రారంభించబడింది"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"యాప్‌లను మార్చడం కోసం ఎగువకు స్వైప్ చేయండి"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"యాప్‌లను శీఘ్రంగా స్విచ్ చేయడానికి కుడి వైపుకు లాగండి"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"స్థూలదృష్టిని టోగుల్ చేయి"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"బ్యాటరీ సేవర్‌ను ఆఫ్ చేయండి"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"రికార్డ్ చేస్తున్నప్పుడు లేదా ప్రసారం చేస్తున్నప్పుడు, మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన సమాచారం మొత్తాన్ని, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> యాక్సెస్ చేయగలుగుతుంది. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, చెల్లింపు వివరాలు, ఫోటోలు, సందేశాలు, మీరు ప్లే చేసే ఆడియో వంటివి ఉంటాయి."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"రికార్డ్ చేస్తున్నప్పుడు లేదా ప్రసారం చేస్తున్నప్పుడు మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన సమాచారం మొత్తాన్ని, ఈ ఫంక్షన్‌ను అందిస్తున్న సర్వీసు యాక్సెస్ చేయగలదు. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, చెల్లింపు వివరాలు, ఫోటోలు, సందేశాలు, మీరు ప్లే చేసే ఆడియో వంటివి ఉంటాయి."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"రికార్డ్ చేయడం లేదా ప్రసారం చేయడం ప్రారంభించాలా?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>తో రికార్డ్ చేయడం లేదా ప్రసారం చేయడం ప్రారంభించాలా?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"మళ్లీ చూపవద్దు"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"అన్నీ క్లియర్ చేయండి"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"నిర్వహించండి"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"నిశ్శబ్ద నోటిఫికేషన్‌లు"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించు"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"అనుకూలపరచండి"</string>
     <string name="notification_done" msgid="6215117625922713976">"పూర్తయింది"</string>
     <string name="inline_undo" msgid="9026953267645116526">"చర్యరద్దు చేయి"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"నోటిఫికేషన్ నియంత్రణలు"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"నోటిఫికేషన్ తాత్కాలిక ఆపివేత ఎంపికలు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 569b05c..54c3d73 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ถูกปิดใช้งาน"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"เปิดใช้งาน NFC แล้ว"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"เลื่อนขึ้นเพื่อสลับแอป"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ลากไปทางขวาเพื่อสลับแอปอย่างรวดเร็ว"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"สลับภาพรวม"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"ปิดโหมดประหยัดแบตเตอรี่"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะมีสิทธิ์เข้าถึงข้อมูลทั้งหมดที่ปรากฏบนหน้าจอหรือเปิดจากอุปกรณ์ของคุณขณะบันทึกหรือแคสต์ ซึ่งรวมถึงข้อมูลอย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน รูปภาพ ข้อความ และเสียงที่คุณเล่น"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"บริการที่มีฟังก์ชันนี้จะมีสิทธิ์เข้าถึงข้อมูลทั้งหมดที่ปรากฏบนหน้าจอหรือเปิดจากอุปกรณ์ของคุณขณะบันทึกหรือแคสต์ ซึ่งรวมถึงข้อมูลอย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน รูปภาพ ข้อความ และเสียงที่คุณเล่น"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"เริ่มบันทึกหรือแคสต์ใช่ไหม"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"เริ่มบันทึกหรือแคสต์ด้วย <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> เลยไหม"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"ไม่ต้องแสดงข้อความนี้อีก"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ล้างทั้งหมด"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"จัดการ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"การแจ้งเตือนแบบไม่มีเสียง"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"การสนทนา"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"ปรับแต่ง"</string>
     <string name="notification_done" msgid="6215117625922713976">"เสร็จสิ้น"</string>
     <string name="inline_undo" msgid="9026953267645116526">"เลิกทำ"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"ส่วนควบคุมการแจ้งเตือน"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ตัวเลือกการปิดเสียงแจ้งเตือนชั่วคราว"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 027eaab..ef812ff 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Naka-disable ang NFC"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Naka-enable ang NFC"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Mag-swipe pataas upang lumipat ng app"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"I-drag pakanan para mabilisang magpalipat-lipat ng app"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"I-toggle ang Overview"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"I-off ang Pangtipid sa Baterya"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"Magkakaroon ng access ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sa lahat ng impormasyong nakikita sa iyong screen o pine-play mula sa device mo habang nagre-record o nagka-cast. Kasama rito ang impormasyong tulad ng mga password, detalye ng pagbabayad, larawan, mensahe, at audio na pine-play mo."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Ang serbisyong nagbibigay ng function na ito ay magkakaroon ng access sa lahat ng impormasyong nakikita sa iyong screen o pine-play mula sa device mo habang nagre-record o nagka-cast. Kasama rito ang impormasyong tulad ng mga password, detalye ng pagbabayad, larawan, mensahe, at audio na pine-play mo."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Magsimulang mag-record o mag-cast?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Simulang mag-record o mag-cast gamit ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Huwag ipakitang muli"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"I-clear lahat"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Pamahalaan"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Mga silent na notification"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Mga Pag-uusap"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"I-clear ang lahat ng silent na notification"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Mga notification na na-pause ng Huwag Istorbohin"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"I-customize"</string>
     <string name="notification_done" msgid="6215117625922713976">"Tapos Na"</string>
     <string name="inline_undo" msgid="9026953267645116526">"I-undo"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"mga kontrol ng notification"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"mga opsyon sa pag-snooze ng notification"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index e9f08d3..470606f 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC devre dışı"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC etkin"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Uygulamalar arasında geçiş yapmak için yukarı kaydırın"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Uygulamaları hızlıca değiştirmek için sağa kaydırın"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Genel bakışı aç/kapat"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Pil Tasarrufu\'nu kapat"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ekranınızda görünen veya kayıt ya da yayın sırasında cihazınızdan oynatılan tüm bilgilere erişecektir. Bu bilgiler arasında şifreler, ödeme detayları, fotoğraflar, mesajlar ve çaldığınız sesler gibi bilgiler yer alır."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Bu işlevi sağlayan hizmet, ekranınızda görünen veya kayıt ya da yayın sırasında cihazınızdan oynatılan tüm bilgilere erişecektir. Bu bilgiler arasında şifreler, ödeme detayları, fotoğraflar, mesajlar ve çaldığınız sesler gibi bilgiler yer alır."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Kayıt veya yayınlama başlatılsın mı?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ile kayıt veya yayınlama başlatılsın mı?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Bir daha gösterme"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tümünü temizle"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Yönet"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Sessiz bildirimler"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Görüşmeler"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sessiz bildirimlerin tümünü temizle"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Özelleştir"</string>
     <string name="notification_done" msgid="6215117625922713976">"Bitti"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Geri al"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"Bildirim kontrolleri"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"bildirim erteleme seçenekleri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 3640c80..496206a 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -395,6 +395,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC вимкнено"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ввімкнено"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Проводьте пальцем угору, щоб переходити між додатками"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Перетягуйте праворуч, щоб швидко переходити між додатками"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Увімкнути або вимкнути огляд"</string>
@@ -477,6 +483,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Очистити все"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Керувати"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Беззвучні сповіщення"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Чати"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Очистити всі беззвучні сповіщення"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Режим \"Не турбувати\" призупинив сповіщення"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
@@ -695,6 +702,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Налаштувати"</string>
     <string name="notification_done" msgid="6215117625922713976">"Готово"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Відмінити"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"елементи керування сповіщеннями"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"параметри відкладення сповіщень"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index fdc618b..a6de509 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"‏NFC غیر فعال ہے"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"‏NFC فعال ہے"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ایپس سوئچ کرنے کیلئے اوپر سوائپ کریں"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"تیزی سے ایپس کو سوئچ کرنے کے لیے دائیں طرف گھسیٹیں"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"مجموعی جائزہ ٹوگل کریں"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"سبھی کو صاف کریں"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"نظم کریں"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"اطلاعات خاموش کریں"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"گفتگوئیں"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"سبھی خاموش اطلاعات کو صاف کریں"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"حسب ضرورت بنائیں"</string>
     <string name="notification_done" msgid="6215117625922713976">"ہوگیا"</string>
     <string name="inline_undo" msgid="9026953267645116526">"کالعدم کریں"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"اطلاع کے کنٹرولز"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"اطلاع اسنوز کرنے کے اختیارات"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index df40325..1eb02f3 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC o‘chiq"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC yoniq"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekranni yozib olish"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Boshlash"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Toʻxtatish"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Ilovalarni almashtirish uchun ekranni tepaga suring"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Ilovalarni tezkor almashtirish uchun o‘ngga torting"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Umumiy nazar rejimini almashtirish"</string>
@@ -465,13 +468,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Quvvat tejash rejimidan chiqish"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ekranda chiqqan yoki yozib olish va translatsiya vaqtida ijro etilgan barcha axborotlarga ruxsat oladi. Bu axborotlar parollar, toʻlov tafsilotlari, rasmlar, xabarlar va ijro etilgan audiolardan iborat boʻlishi mumkin."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Bu funksiyani taʼminlovchi xizmat ekranda chiqqan yoki yozib olish va translatsiya vaqtida ijro etilgan barcha axborotlarga ruxsat oladi. Bu axborotlar parollar, toʻlov tafsilotlari, rasmlar, xabarlar va ijro etilgan audiolardan iborat boʻlishi mumkin."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Yozib olish yoki translatsiya boshlansinmi?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bilan yozib olinsin yoki translatsiya qilinsinmi?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Boshqa ko‘rsatilmasin"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hammasini tozalash"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tovushsiz bildirishnomalar"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha tovushsiz bildirishnomalarni tozalash"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
@@ -690,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Moslash"</string>
     <string name="notification_done" msgid="6215117625922713976">"Tayyor"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Qaytarish"</string>
+    <string name="demote" msgid="6225813324237153980">"Bu bildirishnomani zanjirsiz deb belgilash"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Sevimli"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Sevimlilardan olib tashlash"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Ovozsiz"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Ovozli"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Bir zanjirda chiqarish"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Zanjirlarsiz chiqarish"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Bosh ekranga chiqarish"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"bildirishnoma sozlamalari"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"bildirishnomalarni kechiktirish parametrlari"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 8a99f43..dc3882e 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC đã được tắt"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC đã được bật"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Vuốt lên để chuyển đổi ứng dụng"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Kéo sang phải để chuyển đổi nhanh giữa các ứng dụng"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Bật/tắt chế độ xem Tổng quan"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"Tắt trình tiết kiệm pin"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát từ thiết bị trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"Dịch vụ cung cấp chức năng này có quyền truy cập vào tất cả các thông tin hiển thị trên màn hình của bạn hoặc phát từ thiết bị trong khi ghi âm/ghi hình hoặc truyền, bao gồm cả thông tin như mật khẩu, chi tiết thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"Bắt đầu ghi âm/ghi hình hoặc truyền?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Bắt đầu ghi âm/ghi hình hoặc truyền bằng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"Không hiển thị lại"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Xóa tất cả"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Quản lý"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Thông báo im lặng"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Cuộc trò chuyện"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Xóa tất cả thông báo im lặng"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Tùy chỉnh"</string>
     <string name="notification_done" msgid="6215117625922713976">"Xong"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Hoàn tác"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"điều khiển thông báo"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"Tùy chọn báo lại thông báo"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 66bf66b..baacdae 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已启用"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑动可切换应用"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖动可快速切换应用"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切换概览"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"关闭省电模式"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"在录制或投射内容时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>将可获取您屏幕上显示或设备中播放的所有信息,其中包括密码、付款明细、照片、消息以及您播放的音频等信息。"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"在录制或投射内容时,提供此功能的服务将可获取您屏幕上显示或设备中播放的所有信息,其中包括密码、付款明细、照片、消息以及您播放的音频等信息。"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"要开始录制或投射内容吗?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"要开始使用<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>录制或投射内容吗?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"不再显示"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"无声通知"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有无声通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"勿扰模式暂停的通知"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"自定义"</string>
     <string name="notification_done" msgid="6215117625922713976">"完成"</string>
     <string name="inline_undo" msgid="9026953267645116526">"撤消"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g><xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"通知设置"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"通知延后选项"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index dae6eb1..0f1696e7 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑動即可切換應用程式"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖曳即可快速切換應用程式"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切換概覽"</string>
@@ -471,6 +477,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"靜音通知"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「請勿騷擾」模式已將通知暫停"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
@@ -689,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"自訂"</string>
     <string name="notification_done" msgid="6215117625922713976">"完成"</string>
     <string name="inline_undo" msgid="9026953267645116526">"復原"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"通知控制項"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"通知延後選項"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 1586bb8..e8e76ec 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -391,6 +391,12 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string>
+    <!-- no translation found for quick_settings_screen_record_label (1594046461509776676) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_start (1574725369331638985) -->
+    <skip />
+    <!-- no translation found for quick_settings_screen_record_stop (8087348522976412119) -->
+    <skip />
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑動即可切換應用程式"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖曳即可快速切換應用程式"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切換總覽"</string>
@@ -465,13 +471,13 @@
     <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"關閉節約耗電量模式"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"在錄製或投放內容時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"在錄製或投放內容時,提供這項功能的服務可存取畫面上顯示的任何資訊或裝置播放的任何內容,包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
-    <!-- no translation found for media_projection_dialog_service_title (2888507074107884040) -->
-    <skip />
+    <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"要開始錄製或投放內容嗎?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"要使用「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」開始錄製或投放內容嗎?"</string>
     <string name="media_projection_remember_text" msgid="6896767327140422951">"不要再顯示"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"靜音通知"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「零打擾」模式已將通知設為暫停"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
@@ -690,6 +696,22 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"自訂"</string>
     <string name="notification_done" msgid="6215117625922713976">"完成"</string>
     <string name="inline_undo" msgid="9026953267645116526">"復原"</string>
+    <!-- no translation found for demote (6225813324237153980) -->
+    <skip />
+    <!-- no translation found for notification_conversation_favorite (8252976467488182853) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unfavorite (633301300443356176) -->
+    <skip />
+    <!-- no translation found for notification_conversation_mute (477431709687199671) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unmute (410885000669775294) -->
+    <skip />
+    <!-- no translation found for notification_conversation_bubble (4598142032706190028) -->
+    <skip />
+    <!-- no translation found for notification_conversation_unbubble (2303087159802926401) -->
+    <skip />
+    <!-- no translation found for notification_conversation_home_screen (8347136037958438935) -->
+    <skip />
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"通知控制項"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"通知延後選項"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 5353018..fa764b5 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -391,6 +391,9 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"I-NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"I-NFC ikhutshaziwe"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"I-NFC inikwe amandla"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Irekhodi lesikrini"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Qala"</string>
+    <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Misa"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swayiphela phezulu ukuze ushintshe izinhlelo zokusebenza"</string>
     <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Hudula ngqo ukuze ushintshe ngokushesha izinhlelo zokusebenza"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Guqula ukubuka konke"</string>
@@ -471,6 +474,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Sula konke"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Phatha"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Thulisa izaziso"</string>
+    <string name="notification_section_header_conversations" msgid="821834744538345661">"Izingxoxo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sula zonke izaziso ezithulile"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Izaziso zimiswe okwesikhashana ukungaphazamisi"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
@@ -689,6 +693,14 @@
     <string name="notification_app_settings" msgid="8963648463858039377">"Enza ngendlela oyifisayo"</string>
     <string name="notification_done" msgid="6215117625922713976">"Kwenziwe"</string>
     <string name="inline_undo" msgid="9026953267645116526">"Susa"</string>
+    <string name="demote" msgid="6225813324237153980">"Maka lesi saziso njengokungesiyo ingxoxo"</string>
+    <string name="notification_conversation_favorite" msgid="8252976467488182853">"Intandokazi"</string>
+    <string name="notification_conversation_unfavorite" msgid="633301300443356176">"Susa ubuntandokazi"</string>
+    <string name="notification_conversation_mute" msgid="477431709687199671">"Thulisa"</string>
+    <string name="notification_conversation_unmute" msgid="410885000669775294">"Susa ukuthula"</string>
+    <string name="notification_conversation_bubble" msgid="4598142032706190028">"Bonisa njengebhamuza"</string>
+    <string name="notification_conversation_unbubble" msgid="2303087159802926401">"Vala amabhamuza"</string>
+    <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Faka kusikrini sasekhaya"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="6429668976593634862">"izilawuli zesaziso"</string>
     <string name="notification_menu_snooze_description" msgid="4740133348901973244">"izinketho zokusnuza zesaziso"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 8963157..e520106 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -484,4 +484,13 @@
     <!-- Package name for controls plugin -->
     <string name="config_controlsPluginPackageName" translatable="false">com.android.systemui.controls.panel</string>
 
+    <!-- Defines the blacklist for system icons.  That is to say, the icons in the status bar that
+         are part of the blacklist are never displayed. Each item in the blacklist must be a string
+         defined in core/res/res/config.xml to properly blacklist the icon.
+     -->
+    <string-array name="config_statusBarIconBlackList" translatable="false">
+        <item>@*android:string/status_bar_rotate</item>
+        <item>@*android:string/status_bar_headset</item>
+    </string-array>
+
 </resources>
diff --git a/packages/SystemUI/scripts/update_shared_lib.sh b/packages/SystemUI/scripts/update_shared_lib.sh
new file mode 100755
index 0000000..25f723f
--- /dev/null
+++ b/packages/SystemUI/scripts/update_shared_lib.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+NUM_ARGS=$#
+JAR_DESTINATION="$1/prebuilts/framework_intermediates/quickstep/libs/sysui_shared.jar"
+
+has_croot() {
+  declare -F croot > /dev/null
+  return $?
+}
+
+check_environment() {
+  if ! has_croot; then
+    echo "Run script in a shell that has had envsetup run. Run '. update_shared_lib.sh' from scripts directory"
+    return 1
+  fi
+
+  if [ $NUM_ARGS -ne 1 ]; then
+    echo "Usage: . update_shared_lib PATH_TO_UNBUNDLED_LAUNCER     e.g. . update_shared_lib ~/src/ub-launcher3-master"
+    return 1
+  fi
+  return 0
+}
+
+main() {
+  if check_environment ; then
+    pushd .
+    croot
+    mma -j16 SystemUISharedLib
+    cp out/target/product/$TARGET_PRODUCT/obj/JAVA_LIBRARIES/SystemUISharedLib_intermediates/javalib.jar $JAR_DESTINATION
+    popd
+  fi
+}
+
+main
+
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
new file mode 100644
index 0000000..70a464d
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shared.system;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.view.SurfaceView;
+
+/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */
+public final class UniversalSmartspaceUtils {
+    public static final String ACTION_REQUEST_SMARTSPACE_VIEW =
+            "com.android.systemui.REQUEST_SMARTSPACE_VIEW";
+
+    private static final String SYSUI_PACKAGE = "com.android.systemui";
+    private static final String INTENT_KEY_INPUT_BUNDLE = "input_bundle";
+    private static final String BUNDLE_KEY_INPUT_TOKEN = "input_token";
+    private static final String INTENT_KEY_SURFACE_CONTROL = "surface_control";
+
+    /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */
+    public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) {
+        Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);
+
+        Bundle inputBundle = new Bundle();
+        inputBundle.putBinder(BUNDLE_KEY_INPUT_TOKEN, surfaceView.getInputToken());
+        return intent
+                .putExtra(INTENT_KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl())
+                .putExtra(INTENT_KEY_INPUT_BUNDLE, inputBundle)
+                .setPackage(SYSUI_PACKAGE)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_FOREGROUND);
+    }
+
+    /**
+     * Retrieves the SurfaceControl from an Intent created by
+     * {@link #createRequestSmartspaceIntent(SurfaceView)}.
+     **/
+    public static SurfaceControl getSurfaceControl(Intent intent) {
+        return intent.getParcelableExtra(INTENT_KEY_SURFACE_CONTROL);
+    }
+
+    /**
+     * Retrieves the input token from an Intent created by
+     * {@link #createRequestSmartspaceIntent(SurfaceView)}.
+     **/
+    public static IBinder getInputToken(Intent intent) {
+        Bundle inputBundle = intent.getBundleExtra(INTENT_KEY_INPUT_BUNDLE);
+        return inputBundle == null ? null : inputBundle.getBinder(BUNDLE_KEY_INPUT_TOKEN);
+    }
+
+    private UniversalSmartspaceUtils() {}
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 35a65aa..76adf04 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.annotation.NonNull;
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
 import android.app.Dialog;
@@ -26,6 +27,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.telephony.PinResult;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -35,7 +37,6 @@
 import android.view.WindowManager;
 import android.widget.ImageView;
 
-import com.android.internal.telephony.PhoneConstants;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 
@@ -139,11 +140,11 @@
 
         // Sending empty PIN here to query the number of remaining PIN attempts
         new CheckSimPin("", mSubId) {
-            void onSimCheckResponse(final int result, final int attemptsRemaining) {
-                Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result" + result +
-                        " attemptsRemaining=" + attemptsRemaining);
-                if (attemptsRemaining >= 0) {
-                    mRemainingAttempts = attemptsRemaining;
+            void onSimCheckResponse(final PinResult result) {
+                Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result "
+                        + result.toString());
+                if (result.getAttemptsRemaining() >= 0) {
+                    mRemainingAttempts = result.getAttemptsRemaining();
                     setLockedSimMessage();
                 }
             }
@@ -251,7 +252,7 @@
             mSubId = subId;
         }
 
-        abstract void onSimCheckResponse(final int result, final int attemptsRemaining);
+        abstract void onSimCheckResponse(@NonNull PinResult result);
 
         @Override
         public void run() {
@@ -261,23 +262,23 @@
             TelephonyManager telephonyManager =
                     ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE))
                             .createForSubscriptionId(mSubId);
-            final int[] result = telephonyManager.supplyPinReportResult(mPin);
-            if (result == null || result.length == 0) {
+            final PinResult result = telephonyManager.supplyPinReportPinResult(mPin);
+            if (result == null) {
                 Log.e(TAG, "Error result for supplyPinReportResult.");
                 post(new Runnable() {
                     @Override
                     public void run() {
-                        onSimCheckResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1);
+                        onSimCheckResponse(PinResult.getDefaultFailedResult());
                     }
                 });
             } else {
                 if (DEBUG) {
-                    Log.v(TAG, "supplyPinReportResult returned: " + result[0] + " " + result[1]);
+                    Log.v(TAG, "supplyPinReportResult returned: " + result.toString());
                 }
                 post(new Runnable() {
                     @Override
                     public void run() {
-                        onSimCheckResponse(result[0], result[1]);
+                        onSimCheckResponse(result);
                     }
                 });
             }
@@ -330,17 +331,18 @@
         if (mCheckSimPinThread == null) {
             mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText(), mSubId) {
                 @Override
-                void onSimCheckResponse(final int result, final int attemptsRemaining) {
+                void onSimCheckResponse(final PinResult result) {
                     post(new Runnable() {
                         @Override
                         public void run() {
-                            mRemainingAttempts = attemptsRemaining;
+                            mRemainingAttempts = result.getAttemptsRemaining();
                             if (mSimUnlockProgressDialog != null) {
                                 mSimUnlockProgressDialog.hide();
                             }
                             resetPasswordText(true /* animate */,
-                                    result != PhoneConstants.PIN_RESULT_SUCCESS /* announce */);
-                            if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
+                                    /* announce */
+                                    result.getType() != PinResult.PIN_RESULT_TYPE_SUCCESS);
+                            if (result.getType() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
                                 Dependency.get(KeyguardUpdateMonitor.class)
                                         .reportSimUnlocked(mSubId);
                                 mRemainingAttempts = -1;
@@ -350,14 +352,16 @@
                                 }
                             } else {
                                 mShowDefaultMessage = false;
-                                if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
-                                    if (attemptsRemaining <= 2) {
+                                if (result.getType() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
+                                    if (result.getAttemptsRemaining() <= 2) {
                                         // this is getting critical - show dialog
-                                        getSimRemainingAttemptsDialog(attemptsRemaining).show();
+                                        getSimRemainingAttemptsDialog(
+                                                result.getAttemptsRemaining()).show();
                                     } else {
                                         // show message
                                         mSecurityMessageDisplay.setMessage(
-                                                getPinPasswordErrorMessage(attemptsRemaining, false));
+                                                getPinPasswordErrorMessage(
+                                                        result.getAttemptsRemaining(), false));
                                     }
                                 } else {
                                     // "PIN operation failed!" - no idea what this was and no way to
@@ -367,7 +371,7 @@
                                 }
                                 if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
                                         + " CheckSimPin.onSimCheckResponse: " + result
-                                        + " attemptsRemaining=" + attemptsRemaining);
+                                        + " attemptsRemaining=" + result.getAttemptsRemaining());
                             }
                             mCallback.userActivity();
                             mCheckSimPinThread = null;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index dc68115..10dcbd6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -25,6 +26,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.telephony.PinResult;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -34,7 +36,6 @@
 import android.view.WindowManager;
 import android.widget.ImageView;
 
-import com.android.internal.telephony.PhoneConstants;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 
@@ -191,13 +192,16 @@
 
         // Sending empty PUK here to query the number of remaining PIN attempts
         new CheckSimPuk("", "", mSubId) {
-            void onSimLockChangedResponse(final int result, final int attemptsRemaining) {
-                Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result" + result +
-                        " attemptsRemaining=" + attemptsRemaining);
-                if (attemptsRemaining >= 0) {
-                    mRemainingAttempts = attemptsRemaining;
-                    mSecurityMessageDisplay.setMessage(
-                            getPukPasswordErrorMessage(attemptsRemaining, true));
+            void onSimLockChangedResponse(final PinResult result) {
+                if (result == null) Log.e(LOG_TAG, "onSimCheckResponse, pin result is NULL");
+                else {
+                    Log.d(LOG_TAG, "onSimCheckResponse " + " dummy One result "
+                            + result.toString());
+                    if (result.getAttemptsRemaining() >= 0) {
+                        mRemainingAttempts = result.getAttemptsRemaining();
+                        mSecurityMessageDisplay.setMessage(
+                                getPukPasswordErrorMessage(result.getAttemptsRemaining(), true));
+                    }
                 }
             }
         }.start();
@@ -311,7 +315,7 @@
             mSubId = subId;
         }
 
-        abstract void onSimLockChangedResponse(final int result, final int attemptsRemaining);
+        abstract void onSimLockChangedResponse(@NonNull PinResult result);
 
         @Override
         public void run() {
@@ -319,23 +323,23 @@
             TelephonyManager telephonyManager =
                     ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE))
                             .createForSubscriptionId(mSubId);
-            final int[] result = telephonyManager.supplyPukReportResult(mPuk, mPin);
-            if (result == null || result.length == 0) {
+            final PinResult result = telephonyManager.supplyPukReportPinResult(mPuk, mPin);
+            if (result == null) {
                 Log.e(TAG, "Error result for supplyPukReportResult.");
                 post(new Runnable() {
                     @Override
                     public void run() {
-                        onSimLockChangedResponse(PhoneConstants.PIN_GENERAL_FAILURE, -1);
+                        onSimLockChangedResponse(PinResult.getDefaultFailedResult());
                     }
                 });
             } else {
                 if (DEBUG) {
-                    Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
+                    Log.v(TAG, "supplyPukReportResult returned: " + result.toString());
                 }
                 post(new Runnable() {
                     @Override
                     public void run() {
-                        onSimLockChangedResponse(result[0], result[1]);
+                        onSimLockChangedResponse(result);
                     }
                 });
             }
@@ -402,7 +406,7 @@
         if (mCheckSimPukThread == null) {
             mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText, mSubId) {
                 @Override
-                void onSimLockChangedResponse(final int result, final int attemptsRemaining) {
+                void onSimLockChangedResponse(final PinResult result) {
                     post(new Runnable() {
                         @Override
                         public void run() {
@@ -410,29 +414,32 @@
                                 mSimUnlockProgressDialog.hide();
                             }
                             resetPasswordText(true /* animate */,
-                                    result != PhoneConstants.PIN_RESULT_SUCCESS /* announce */);
-                            if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
+                                    /* announce */
+                                    result.getType() != PinResult.PIN_RESULT_TYPE_SUCCESS);
+                            if (result.getType() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
                                 Dependency.get(KeyguardUpdateMonitor.class)
                                         .reportSimUnlocked(mSubId);
                                 mRemainingAttempts = -1;
                                 mShowDefaultMessage = true;
                                 if (mCallback != null) {
-                                    mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
+                                    mCallback.dismiss(true,
+                                            KeyguardUpdateMonitor.getCurrentUser());
                                 }
                             } else {
                                 mShowDefaultMessage = false;
-                                if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {
+                                if (result.getType() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
                                     // show message
                                     mSecurityMessageDisplay.setMessage(getPukPasswordErrorMessage(
-                                            attemptsRemaining, false));
-                                    if (attemptsRemaining <= 2) {
+                                            result.getAttemptsRemaining(), false));
+                                    if (result.getAttemptsRemaining() <= 2) {
                                         // this is getting critical - show dialog
-                                        getPukRemainingAttemptsDialog(attemptsRemaining).show();
+                                        getPukRemainingAttemptsDialog(
+                                                result.getAttemptsRemaining()).show();
                                     } else {
                                         // show message
                                         mSecurityMessageDisplay.setMessage(
                                                 getPukPasswordErrorMessage(
-                                                attemptsRemaining, false));
+                                                        result.getAttemptsRemaining(), false));
                                     }
                                 } else {
                                     mSecurityMessageDisplay.setMessage(getContext().getString(
@@ -440,7 +447,7 @@
                                 }
                                 if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock "
                                         + " UpdateSim.onSimCheckResponse: "
-                                        + " attemptsRemaining=" + attemptsRemaining);
+                                        + " attemptsRemaining=" + result.getAttemptsRemaining());
                                 mStateMachine.reset();
                             }
                             mCheckSimPukThread = null;
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index d68fe15..a46ab3a 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -288,7 +288,8 @@
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
-            ArraySet<String> icons = StatusBarIconController.getIconBlacklist(newValue);
+            ArraySet<String> icons = StatusBarIconController.getIconBlacklist(
+                    getContext(), newValue);
             setVisibility(icons.contains(mSlotBattery) ? View.GONE : View.VISIBLE);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index d149591..aacc2c4 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -89,6 +89,7 @@
 import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -238,7 +239,8 @@
     @Inject Lazy<LeakReporter> mLeakReporter;
     @Inject Lazy<GarbageMonitor> mGarbageMonitor;
     @Inject Lazy<TunerService> mTunerService;
-    @Inject Lazy<StatusBarWindowController> mStatusBarWindowController;
+    @Inject Lazy<NotificationShadeWindowController> mNotificationShadeWindowController;
+    @Inject Lazy<StatusBarWindowController> mTempStatusBarWindowController;
     @Inject Lazy<DarkIconDispatcher> mDarkIconDispatcher;
     @Inject Lazy<ConfigurationController> mConfigurationController;
     @Inject Lazy<StatusBarIconController> mStatusBarIconController;
@@ -400,7 +402,10 @@
 
         mProviders.put(TunerService.class, mTunerService::get);
 
-        mProviders.put(StatusBarWindowController.class, mStatusBarWindowController::get);
+        mProviders.put(NotificationShadeWindowController.class,
+                mNotificationShadeWindowController::get);
+
+        mProviders.put(StatusBarWindowController.class, mTempStatusBarWindowController::get);
 
         mProviders.put(DarkIconDispatcher.class, mDarkIconDispatcher::get);
 
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index c533755..db8b583 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -455,17 +455,25 @@
     private void setupStatusBarPadding(int padding) {
         // Add some padding to all the content near the edge of the screen.
         StatusBar statusBar = mStatusBarLazy.get();
-        View statusBarWindow = statusBar.getStatusBarWindow();
-        if (statusBarWindow != null) {
-            TunablePadding.addTunablePadding(statusBarWindow.findViewById(R.id.keyguard_header),
+        final View notificationShadeWindowView = statusBar.getNotificationShadeWindowView();
+        if (notificationShadeWindowView != null) {
+            TunablePadding.addTunablePadding(
+                    notificationShadeWindowView.findViewById(R.id.keyguard_header),
                     PADDING, padding, FLAG_END);
 
-            FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBarWindow);
-            fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
-                    new TunablePaddingTagListener(padding, R.id.status_bar));
+            final FragmentHostManager fragmentHostManager =
+                    FragmentHostManager.get(notificationShadeWindowView);
             fragmentHostManager.addTagListener(QS.TAG,
                     new TunablePaddingTagListener(padding, R.id.header));
         }
+
+        final View statusBarWindow = statusBar.getStatusBarWindow();
+        if (statusBarWindow != null) {
+            final FragmentHostManager fragmentHostManager =
+                    FragmentHostManager.get(statusBarWindow);
+            fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
+                    new TunablePaddingTagListener(padding, R.id.status_bar));
+        }
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 84a592d..7b4816f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -162,6 +163,7 @@
     private Bundle mBiometricPromptBundle;
     private boolean mRequireConfirmation;
     private int mUserId;
+    private int mEffectiveUserId;
     @AuthDialog.DialogSize int mSize = AuthDialog.SIZE_UNKNOWN;
 
     private TextView mTitleView;
@@ -280,6 +282,10 @@
         mUserId = userId;
     }
 
+    public void setEffectiveUserId(int effectiveUserId) {
+        mEffectiveUserId = effectiveUserId;
+    }
+
     public void setRequireConfirmation(boolean requireConfirmation) {
         mRequireConfirmation = requireConfirmation;
     }
@@ -650,8 +656,9 @@
         if (isDeviceCredentialAllowed()) {
 
             final @Utils.CredentialType int credentialType =
-                    Utils.getCredentialType(mContext, mUserId);
-            switch(credentialType) {
+                    Utils.getCredentialType(mContext, mEffectiveUserId);
+
+            switch (credentialType) {
                 case Utils.CREDENTIAL_PIN:
                     negativeText = getResources().getString(R.string.biometric_dialog_use_pin);
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 36c89fd..4312a52 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -30,6 +30,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.UserManager;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -75,6 +76,7 @@
     @interface ContainerState {}
 
     final Config mConfig;
+    final int mEffectiveUserId;
     private final Handler mHandler;
     private final Injector mInjector;
     private final IBinder mWindowToken = new Binder();
@@ -182,6 +184,14 @@
         int getAnimateCredentialStartDelayMs() {
             return AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS;
         }
+
+        UserManager getUserManager(Context context) {
+            return UserManager.get(context);
+        }
+
+        int getCredentialType(Context context, int effectiveUserId) {
+            return Utils.getCredentialType(context, effectiveUserId);
+        }
     }
 
     @VisibleForTesting
@@ -230,6 +240,9 @@
         mConfig = config;
         mInjector = injector;
 
+        mEffectiveUserId = mInjector.getUserManager(mContext)
+                .getCredentialOwnerProfile(mConfig.mUserId);
+
         mHandler = new Handler(Looper.getMainLooper());
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
@@ -268,7 +281,6 @@
         mBiometricScrollView = mInjector.getBiometricScrollView(mFrameLayout);
         mBackgroundView = mInjector.getBackgroundView(mFrameLayout);
 
-
         if (isManagedProfile) {
             final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background,
                     mContext.getTheme());
@@ -307,6 +319,7 @@
         mBiometricView.setCallback(mBiometricCallback);
         mBiometricView.setBackgroundView(mBackgroundView);
         mBiometricView.setUserId(mConfig.mUserId);
+        mBiometricView.setEffectiveUserId(mEffectiveUserId);
         mBiometricScrollView.addView(mBiometricView);
     }
 
@@ -318,7 +331,10 @@
      */
     private void addCredentialView(boolean animatePanel, boolean animateContents) {
         final LayoutInflater factory = LayoutInflater.from(mContext);
-        final int credentialType = Utils.getCredentialType(mContext, mConfig.mUserId);
+
+        final @Utils.CredentialType int credentialType = mInjector.getCredentialType(
+                mContext, mEffectiveUserId);
+
         switch (credentialType) {
             case Utils.CREDENTIAL_PATTERN:
                 mCredentialView = (AuthCredentialView) factory.inflate(
@@ -334,7 +350,8 @@
         }
 
         mCredentialView.setContainerView(this);
-        mCredentialView.setUser(mConfig.mUserId);
+        mCredentialView.setEffectiveUserId(mEffectiveUserId);
+        mCredentialView.setCredentialType(credentialType);
         mCredentialView.setCallback(mCredentialCallback);
         mCredentialView.setBiometricPromptBundle(mConfig.mBiometricPromptBundle);
         mCredentialView.setPanelController(mPanelController, animatePanel);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index e0ca1ac..875619a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -338,7 +338,13 @@
 
     @Override
     public void hideAuthenticationDialog() {
-        if (DEBUG) Log.d(TAG, "hideAuthenticationDialog");
+        if (DEBUG) Log.d(TAG, "hideAuthenticationDialog: " + mCurrentDialog);
+
+        if (mCurrentDialog == null) {
+            // Could be possible if the caller canceled authentication after credential success
+            // but before the client was notified.
+            return;
+        }
 
         mCurrentDialog.dismissFromSystemServer();
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
index bebaa4b..ccfd3a5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
@@ -96,7 +96,7 @@
     }
 
     private void checkPasswordAndUnlock() {
-        try (LockscreenCredential password =  mCredentialType == Utils.CREDENTIAL_PIN
+        try (LockscreenCredential password = mCredentialType == Utils.CREDENTIAL_PIN
                 ? LockscreenCredential.createPinOrNone(mPasswordField.getText())
                 : LockscreenCredential.createPasswordOrNone(mPasswordField.getText())) {
             if (password.isNone()) {
@@ -104,7 +104,7 @@
             }
 
             mPendingLockCheck = LockPatternChecker.checkCredential(mLockPatternUtils,
-                    password, mUserId, this::onCredentialChecked);
+                    password, mEffectiveUserId, this::onCredentialChecked);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
index 14414a4..1cb532b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
@@ -69,7 +69,7 @@
                 mPendingLockCheck = LockPatternChecker.checkCredential(
                         mLockPatternUtils,
                         credential,
-                        mUserId,
+                        mEffectiveUserId,
                         this::onPatternChecked);
             }
         }
@@ -99,7 +99,8 @@
         super.onFinishInflate();
         mLockPatternView = findViewById(R.id.lockPattern);
         mLockPatternView.setOnPatternListener(new UnlockPatternListener());
-        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(mUserId));
+        mLockPatternView.setInStealthMode(
+                !mLockPatternUtils.isVisiblePatternEnabled(mEffectiveUserId));
         mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
index 8c8611e..8f2cf70 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
@@ -63,7 +63,7 @@
     protected AuthContainerView mContainerView;
     protected Callback mCallback;
     protected AsyncTask<?, ?, ?> mPendingLockCheck;
-    protected int mUserId;
+    protected int mEffectiveUserId;
     protected ErrorTimer mErrorTimer;
 
     interface Callback {
@@ -137,8 +137,12 @@
         view.setText(string);
     }
 
-    void setUser(int user) {
-        mUserId = user;
+    void setEffectiveUserId(int effectiveUserId) {
+        mEffectiveUserId = effectiveUserId;
+    }
+
+    void setCredentialType(@Utils.CredentialType int credentialType) {
+        mCredentialType = credentialType;
     }
 
     void setCallback(Callback callback) {
@@ -166,8 +170,6 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
 
-        mCredentialType = Utils.getCredentialType(mContext, mUserId);
-
         setText(mTitleView, mBiometricPromptBundle.getString(BiometricPrompt.KEY_TITLE));
         setTextOrHide(mSubtitleView,
                 mBiometricPromptBundle.getString(BiometricPrompt.KEY_SUBTITLE));
@@ -230,7 +232,8 @@
         } else {
             if (timeoutMs > 0) {
                 mHandler.removeCallbacks(mClearErrorRunnable);
-                long deadline = mLockPatternUtils.setLockoutAttemptDeadline(mUserId, timeoutMs);
+                long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+                        mEffectiveUserId, timeoutMs);
                 mErrorTimer = new ErrorTimer(mContext,
                         deadline - SystemClock.elapsedRealtime(),
                         LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS,
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index d835ee1..644d8c4 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -89,9 +89,9 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -166,7 +166,7 @@
     private final HashSet<String> mUserBlockedBubbles;
 
     // Bubbles get added to the status bar view
-    private final StatusBarWindowController mStatusBarWindowController;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final ZenModeController mZenModeController;
     private StatusBarStateListener mStatusBarStateListener;
     private final ScreenshotHelper mScreenshotHelper;
@@ -245,7 +245,7 @@
 
     @Inject
     public BubbleController(Context context,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             StatusBarStateController statusBarStateController,
             ShadeController shadeController,
             BubbleData data,
@@ -256,14 +256,14 @@
             NotificationGroupManager groupManager,
             NotificationEntryManager entryManager,
             RemoteInputUriController remoteInputUriController) {
-        this(context, statusBarWindowController, statusBarStateController, shadeController,
+        this(context, notificationShadeWindowController, statusBarStateController, shadeController,
                 data, null /* synchronizer */, configurationController, interruptionStateProvider,
                 zenModeController, notifUserManager, groupManager, entryManager,
                 remoteInputUriController);
     }
 
     public BubbleController(Context context,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             StatusBarStateController statusBarStateController,
             ShadeController shadeController,
             BubbleData data,
@@ -324,7 +324,7 @@
                     }
                 });
 
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mStatusBarStateListener = new StatusBarStateListener();
         statusBarStateController.addCallback(mStatusBarStateListener);
 
@@ -377,10 +377,10 @@
     private void ensureStackViewCreated() {
         if (mStackView == null) {
             mStackView = new BubbleStackView(mContext, mBubbleData, mSurfaceSynchronizer);
-            ViewGroup sbv = mStatusBarWindowController.getStatusBarView();
-            int bubbleScrimIndex = sbv.indexOfChild(sbv.findViewById(R.id.scrim_for_bubble));
+            ViewGroup nsv = mNotificationShadeWindowController.getNotificationShadeView();
+            int bubbleScrimIndex = nsv.indexOfChild(nsv.findViewById(R.id.scrim_for_bubble));
             int stackIndex = bubbleScrimIndex + 1;  // Show stack above bubble scrim.
-            sbv.addView(mStackView, stackIndex,
+            nsv.addView(mStackView, stackIndex,
                     new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
             if (mExpandListener != null) {
                 mStackView.setExpandListener(mExpandListener);
@@ -473,7 +473,7 @@
             if (listener != null) {
                 listener.onBubbleExpandChanged(isExpanding, key);
             }
-            mStatusBarWindowController.setBubbleExpanded(isExpanding);
+            mNotificationShadeWindowController.setBubbleExpanded(isExpanding);
         });
         if (mStackView != null) {
             mStackView.setExpandListener(mExpandListener);
@@ -944,9 +944,9 @@
         }
 
         // Let listeners know if bubble state changed.
-        boolean hadBubbles = mStatusBarWindowController.getBubblesShowing();
+        boolean hadBubbles = mNotificationShadeWindowController.getBubblesShowing();
         boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE;
-        mStatusBarWindowController.setBubblesShowing(hasBubblesShowing);
+        mNotificationShadeWindowController.setBubblesShowing(hasBubblesShowing);
         if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) {
             mStateChangeListener.onHasBubblesChanged(hasBubblesShowing);
         }
@@ -983,7 +983,7 @@
                 && context.getDisplay().getDisplayId() == DEFAULT_DISPLAY;
         final Bubble expandedBubble = mStackView.getExpandedBubble();
         if (defaultDisplay && expandedBubble != null && isStackExpanded()
-                && !mStatusBarWindowController.getPanelExpanded()) {
+                && !mNotificationShadeWindowController.getPanelExpanded()) {
             return expandedBubble;
         }
         return null;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index c138462..36a4a10 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -97,8 +97,8 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
 import com.android.systemui.plugins.GlobalActionsPanelPlugin;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.EmergencyDialerConstants;
@@ -1528,7 +1528,7 @@
         private float mScrimAlpha;
         private ResetOrientationData mResetOrientationData;
         private boolean mHadTopUi;
-        private final StatusBarWindowController mStatusBarWindowController;
+        private final NotificationShadeWindowController mNotificationShadeWindowController;
         private boolean mControlsEnabled;
 
         ActionsDialog(Context context, MyAdapter adapter,
@@ -1539,7 +1539,8 @@
             mAdapter = adapter;
             mColorExtractor = Dependency.get(SysuiColorExtractor.class);
             mStatusBarService = Dependency.get(IStatusBarService.class);
-            mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
+            mNotificationShadeWindowController =
+                    Dependency.get(NotificationShadeWindowController.class);
             mControlsEnabled = controlsEnabled;
 
             // Window initialization
@@ -1721,8 +1722,8 @@
         public void show() {
             super.show();
             mShowing = true;
-            mHadTopUi = mStatusBarWindowController.getForceHasTopUi();
-            mStatusBarWindowController.setForceHasTopUi(true);
+            mHadTopUi = mNotificationShadeWindowController.getForceHasTopUi();
+            mNotificationShadeWindowController.setForceHasTopUi(true);
             mBackgroundDrawable.setAlpha(0);
             mGlobalActionsLayout.setTranslationX(mGlobalActionsLayout.getAnimationOffsetX());
             mGlobalActionsLayout.setTranslationY(mGlobalActionsLayout.getAnimationOffsetY());
@@ -1775,7 +1776,7 @@
         }
 
         private void completeDismiss() {
-            mStatusBarWindowController.setForceHasTopUi(mHadTopUi);
+            mNotificationShadeWindowController.setForceHasTopUi(mHadTopUi);
             super.dismiss();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e13c3e0..2fc7a9c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -88,9 +88,9 @@
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.util.InjectionInflationController;
 
 import java.io.FileDescriptor;
@@ -212,7 +212,7 @@
     private AlarmManager mAlarmManager;
     private AudioManager mAudioManager;
     private StatusBarManager mStatusBarManager;
-    private final StatusBarWindowController mStatusBarWindowController;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final Executor mUiBgExecutor;
 
     private boolean mSystemReady;
@@ -691,7 +691,7 @@
             FalsingManager falsingManager,
             LockPatternUtils lockPatternUtils,
             BroadcastDispatcher broadcastDispatcher,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManagerLazy,
             DismissCallbackRegistry dismissCallbackRegistry,
             @UiBackground Executor uiBgExecutor) {
@@ -699,7 +699,7 @@
         mFalsingManager = falsingManager;
         mLockPatternUtils = lockPatternUtils;
         mBroadcastDispatcher = broadcastDispatcher;
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mStatusBarKeyguardViewManagerLazy = statusBarKeyguardViewManagerLazy;
         mDismissCallbackRegistry = dismissCallbackRegistry;
         mUiBgExecutor = uiBgExecutor;
@@ -1819,7 +1819,7 @@
             adjustStatusBarLocked();
             userActivity();
             mUpdateMonitor.setKeyguardGoingAway(false);
-            mStatusBarWindowController.setKeyguardGoingAway(false);
+            mNotificationShadeWindowController.setKeyguardGoingAway(false);
             mShowKeyguardWakeLock.release();
         }
         mKeyguardDisplayManager.show();
@@ -1852,7 +1852,7 @@
             }
 
             mUpdateMonitor.setKeyguardGoingAway(true);
-            mStatusBarWindowController.setKeyguardGoingAway(true);
+            mNotificationShadeWindowController.setKeyguardGoingAway(true);
 
             // Don't actually hide the Keyguard at the moment, wait for window
             // manager until it tells us it's safe to do so with
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 6afa0bf..eba2e78 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -19,17 +19,11 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 
-import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN;
-import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.systemui.Interpolators.LINEAR_OUT_SLOW_IN;
-
 import android.animation.AnimationHandler;
 import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.RectEvaluator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.animation.TimeAnimator;
+import android.annotation.Nullable;
 import android.app.ActivityManager.StackInfo;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
@@ -42,13 +36,16 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Log;
-import android.view.animation.Interpolator;
+
+import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.internal.os.SomeArgs;
 import com.android.systemui.pip.PipSnapAlgorithm;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.util.animation.FloatProperties;
+import com.android.systemui.util.animation.PhysicsAnimator;
 
 import java.io.PrintWriter;
 
@@ -60,18 +57,14 @@
     private static final String TAG = "PipMotionHelper";
     private static final boolean DEBUG = false;
 
-    private static final RectEvaluator RECT_EVALUATOR = new RectEvaluator(new Rect());
-
-    private static final int DEFAULT_MOVE_STACK_DURATION = 225;
-    private static final int SNAP_STACK_DURATION = 225;
-    private static final int DRAG_TO_TARGET_DISMISS_STACK_DURATION = 375;
-    private static final int DRAG_TO_DISMISS_STACK_DURATION = 175;
     private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
     private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
     private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 300;
-    private static final int MINIMIZE_STACK_MAX_DURATION = 200;
     private static final int SHIFT_DURATION = 300;
 
+    /** Friction to use for PIP when it moves via physics fling animations. */
+    private static final float DEFAULT_FRICTION = 2f;
+
     // The fraction of the stack width that the user has to drag offscreen to minimize the PiP
     private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.3f;
     // The fraction of the stack height that the user has to drag offscreen to dismiss the PiP
@@ -89,12 +82,39 @@
     private PipMenuActivityController mMenuController;
     private PipSnapAlgorithm mSnapAlgorithm;
     private FlingAnimationUtils mFlingAnimationUtils;
-    private AnimationHandler mAnimationHandler;
 
-    private final Rect mBounds = new Rect();
     private final Rect mStableInsets = new Rect();
 
-    private ValueAnimator mBoundsAnimator = null;
+    /** PIP's current bounds on the screen. */
+    private final Rect mBounds = new Rect();
+
+    /**
+     * Bounds that are animated using the physics animator. PIP is moved to these bounds whenever
+     * the {@link #mVsyncTimeAnimator} ticks.
+     */
+    private final Rect mAnimatedBounds = new Rect();
+
+    /**
+     * PhysicsAnimator instance for animating {@link #mAnimatedBounds} using physics animations.
+     */
+    private PhysicsAnimator<Rect> mAnimatedBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
+            mAnimatedBounds);
+
+    /**
+     * Time animator whose frame timing comes from the SurfaceFlinger vsync frame provider. At each
+     * frame, PIP is moved to {@link #mAnimatedBounds}, which are animated asynchronously using
+     * physics animations.
+     */
+    private TimeAnimator mVsyncTimeAnimator;
+
+    /** FlingConfig instances provided to PhysicsAnimator for fling gestures. */
+    private PhysicsAnimator.FlingConfig mFlingConfigX;
+    private PhysicsAnimator.FlingConfig mFlingConfigY;
+
+    /** SpringConfig to use for fling-then-spring animations. */
+    private final PhysicsAnimator.SpringConfig mSpringConfig =
+            new PhysicsAnimator.SpringConfig(
+                    SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
 
     public PipMotionHelper(Context context, IActivityManager activityManager,
             IActivityTaskManager activityTaskManager, PipMenuActivityController menuController,
@@ -106,9 +126,39 @@
         mMenuController = menuController;
         mSnapAlgorithm = snapAlgorithm;
         mFlingAnimationUtils = flingAnimationUtils;
-        mAnimationHandler = new AnimationHandler();
-        mAnimationHandler.setProvider(new SfVsyncFrameCallbackProvider());
+        final AnimationHandler vsyncFrameCallbackProvider = new AnimationHandler();
+        vsyncFrameCallbackProvider.setProvider(new SfVsyncFrameCallbackProvider());
+
         onConfigurationChanged();
+
+        // Construct a time animator that uses the vsync frame provider. Physics animations can't
+        // use custom frame providers, since they rely on constant time between frames to run the
+        // physics simulations. To work around this, we physically-animate a second set of bounds,
+        // and apply those animating bounds to the PIP in-sync via this TimeAnimator.
+        mVsyncTimeAnimator = new TimeAnimator() {
+            @Override
+            public AnimationHandler getAnimationHandler() {
+                return vsyncFrameCallbackProvider;
+            }
+        };
+
+        // When the time animator ticks, move PIP to the animated bounds.
+        mVsyncTimeAnimator.setTimeListener(
+                (animation, totalTime, deltaTime) ->
+                        resizePipUnchecked(mAnimatedBounds));
+
+        // Add a listener for cancel/end events that moves PIP to the final animated bounds.
+        mVsyncTimeAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                resizePipUnchecked(mAnimatedBounds);
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                resizePipUnchecked(mAnimatedBounds);
+            }
+        });
     }
 
     /**
@@ -241,88 +291,85 @@
     }
 
     /**
-     * Flings the minimized PiP to the closest minimized snap target.
-     */
-    Rect flingToMinimizedState(float velocityY, Rect movementBounds, Point dragStartPosition) {
-        cancelAnimations();
-        // We currently only allow flinging the minimized stack up and down, so just lock the
-        // movement bounds to the current stack bounds horizontally
-        movementBounds = new Rect(mBounds.left, movementBounds.top, mBounds.left,
-                movementBounds.bottom);
-        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                0 /* velocityX */, velocityY, dragStartPosition);
-        if (!mBounds.equals(toBounds)) {
-            mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
-            mFlingAnimationUtils.apply(mBoundsAnimator, 0,
-                    distanceBetweenRectOffsets(mBounds, toBounds),
-                    velocityY);
-            mBoundsAnimator.start();
-        }
-        return toBounds;
-    }
-
-    /**
      * Animates the PiP to the minimized state, slightly offscreen.
      */
-    Rect animateToClosestMinimizedState(Rect movementBounds,
-            AnimatorUpdateListener updateListener) {
-        cancelAnimations();
-        Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds);
-        if (!mBounds.equals(toBounds)) {
-            mBoundsAnimator = createAnimationToBounds(mBounds, toBounds,
-                    MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN);
-            if (updateListener != null) {
-                mBoundsAnimator.addUpdateListener(updateListener);
-            }
-            mBoundsAnimator.start();
+    void animateToClosestMinimizedState(Rect movementBounds, @Nullable Runnable updateAction) {
+        final Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds);
+
+        prepareForBoundsAnimation(movementBounds);
+
+        mAnimatedBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, toBounds.left, mSpringConfig)
+                .spring(FloatProperties.RECT_Y, toBounds.top, mSpringConfig);
+
+        if (updateAction != null) {
+            mAnimatedBoundsPhysicsAnimator.addUpdateListener(
+                    (target, values) -> updateAction.run());
         }
-        return toBounds;
+
+        startBoundsAnimation();
     }
 
     /**
      * Flings the PiP to the closest snap target.
      */
-    Rect flingToSnapTarget(float velocity, float velocityX, float velocityY, Rect movementBounds,
-            AnimatorUpdateListener updateListener, AnimatorListener listener,
-            Point startPosition) {
-        cancelAnimations();
-        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
-                velocityX, velocityY, startPosition);
-        if (!mBounds.equals(toBounds)) {
-            mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
-            mFlingAnimationUtils.apply(mBoundsAnimator, 0,
-                    distanceBetweenRectOffsets(mBounds, toBounds),
-                    velocity);
-            if (updateListener != null) {
-                mBoundsAnimator.addUpdateListener(updateListener);
-            }
-            if (listener != null){
-                mBoundsAnimator.addListener(listener);
-            }
-            mBoundsAnimator.start();
-        }
-        return toBounds;
+    void flingToSnapTarget(
+            float velocityX, float velocityY, Rect movementBounds, Runnable updateAction,
+            @Nullable Runnable endAction) {
+        prepareForBoundsAnimation(movementBounds);
+
+        mAnimatedBoundsPhysicsAnimator
+                .flingThenSpring(
+                        FloatProperties.RECT_X, velocityX, mFlingConfigX, mSpringConfig,
+                        true /* flingMustReachMinOrMax */)
+                .flingThenSpring(
+                        FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig)
+                .addUpdateListener((target, values) -> updateAction.run())
+                .withEndActions(endAction);
+
+        startBoundsAnimation();
     }
 
     /**
      * Animates the PiP to the closest snap target.
      */
-    Rect animateToClosestSnapTarget(Rect movementBounds, AnimatorUpdateListener updateListener,
-            AnimatorListener listener) {
-        cancelAnimations();
-        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds);
-        if (!mBounds.equals(toBounds)) {
-            mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, SNAP_STACK_DURATION,
-                    FAST_OUT_SLOW_IN);
-            if (updateListener != null) {
-                mBoundsAnimator.addUpdateListener(updateListener);
-            }
-            if (listener != null){
-                mBoundsAnimator.addListener(listener);
-            }
-            mBoundsAnimator.start();
+    void animateToClosestSnapTarget(Rect movementBounds) {
+        prepareForBoundsAnimation(movementBounds);
+
+        final Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds);
+        mAnimatedBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, toBounds.left, mSpringConfig)
+                .spring(FloatProperties.RECT_Y, toBounds.top, mSpringConfig);
+
+        startBoundsAnimation();
+    }
+
+    /**
+     * Animates the dismissal of the PiP off the edge of the screen.
+     */
+    void animateDismiss(float velocityX, float velocityY, @Nullable Runnable updateAction) {
+        final float velocity = PointF.length(velocityX, velocityY);
+        final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond();
+        final Point dismissEndPoint = getDismissEndPoint(mBounds, velocityX, velocityY, isFling);
+
+        // Set the animated bounds to start at the current bounds. We don't need to rebuild the
+        // fling configs here via prepareForBoundsAnimation, since animateDismiss isn't provided
+        // with new movement bounds.
+        mAnimatedBounds.set(mBounds);
+
+        // Animate to the dismiss end point, and then dismiss PIP.
+        mAnimatedBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, dismissEndPoint.x, velocityX, mSpringConfig)
+                .spring(FloatProperties.RECT_Y, dismissEndPoint.y, velocityY, mSpringConfig)
+                .withEndActions(this::dismissPip);
+
+        // If we were provided with an update action, run it whenever there's an update.
+        if (updateAction != null) {
+            mAnimatedBoundsPhysicsAnimator.addUpdateListener(
+                    (target, values) -> updateAction.run());
         }
-        return toBounds;
+
+        startBoundsAnimation();
     }
 
     /**
@@ -378,64 +425,42 @@
     }
 
     /**
-     * Animates the dismissal of the PiP off the edge of the screen.
-     */
-    Rect animateDismiss(Rect pipBounds, float velocityX, float velocityY,
-            AnimatorUpdateListener listener) {
-        cancelAnimations();
-        final float velocity = PointF.length(velocityX, velocityY);
-        final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond();
-        Point p = getDismissEndPoint(pipBounds, velocityX, velocityY, isFling);
-        Rect toBounds = new Rect(pipBounds);
-        toBounds.offsetTo(p.x, p.y);
-        mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DRAG_TO_DISMISS_STACK_DURATION,
-                FAST_OUT_LINEAR_IN);
-        mBoundsAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                dismissPip();
-            }
-        });
-        if (isFling) {
-            mFlingAnimationUtils.apply(mBoundsAnimator, 0,
-                    distanceBetweenRectOffsets(mBounds, toBounds), velocity);
-        }
-        if (listener != null) {
-            mBoundsAnimator.addUpdateListener(listener);
-        }
-        mBoundsAnimator.start();
-        return toBounds;
-    }
-
-    /**
      * Cancels all existing animations.
      */
-    void cancelAnimations() {
-        if (mBoundsAnimator != null) {
-            mBoundsAnimator.cancel();
-            mBoundsAnimator = null;
-        }
+    private void cancelAnimations() {
+        mAnimatedBoundsPhysicsAnimator.cancel();
+        mVsyncTimeAnimator.cancel();
     }
 
     /**
-     * Creates an animation to move the PiP to give given {@param toBounds}.
+     * Set new fling configs whose min/max values respect the given movement bounds, and set the
+     * animated bounds to PIP's current 'real' bounds.
      */
-    private ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration,
-            Interpolator interpolator) {
-        ValueAnimator anim = new ValueAnimator() {
-            @Override
-            public AnimationHandler getAnimationHandler() {
-                return mAnimationHandler;
-            }
-        };
-        anim.setObjectValues(fromBounds, toBounds);
-        anim.setEvaluator(RECT_EVALUATOR);
-        anim.setDuration(duration);
-        anim.setInterpolator(interpolator);
-        anim.addUpdateListener((ValueAnimator animation) -> {
-            resizePipUnchecked((Rect) animation.getAnimatedValue());
-        });
-        return anim;
+    private void prepareForBoundsAnimation(Rect movementBounds) {
+        mFlingConfigX = new PhysicsAnimator.FlingConfig(
+                DEFAULT_FRICTION, movementBounds.left, movementBounds.right);
+        mFlingConfigY = new PhysicsAnimator.FlingConfig(
+                DEFAULT_FRICTION, movementBounds.top, movementBounds.bottom);
+
+        mAnimatedBounds.set(mBounds);
+    }
+
+    /**
+     * Starts the physics animator which will update the animated PIP bounds using physics
+     * animations, as well as the TimeAnimator which will apply those bounds to PIP at intervals
+     * synchronized with the SurfaceFlinger vsync frame provider.
+     *
+     * This will also add end actions to the bounds animator that cancel the TimeAnimator and update
+     * the 'real' bounds to equal the final animated bounds.
+     */
+    private void startBoundsAnimation() {
+        cancelAnimations();
+
+        mAnimatedBoundsPhysicsAnimator
+                .withEndActions(
+                        mVsyncTimeAnimator::cancel)
+                .start();
+        mVsyncTimeAnimator.start();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 95e3444..09f1638 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -20,10 +20,6 @@
 import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
 import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
 import android.content.ComponentName;
@@ -111,13 +107,6 @@
             }
         }
     };
-    private ValueAnimator.AnimatorUpdateListener mUpdateScrimListener =
-            new AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    updateDismissFraction();
-                }
-            };
 
     // Behaviour states
     private int mMenuState = MENU_STATE_NONE;
@@ -162,7 +151,7 @@
         @Override
         public void onPipMinimize() {
             setMinimizedStateInternal(true);
-            mMotionHelper.animateToClosestMinimizedState(mMovementBounds, null /* updateListener */);
+            mMotionHelper.animateToClosestMinimizedState(mMovementBounds, null /* updateAction */);
         }
 
         @Override
@@ -655,15 +644,6 @@
                 float lastY = mStartPosition.y + mDelta.y;
                 float left = lastX + lastDelta.x;
                 float top = lastY + lastDelta.y;
-                if (!touchState.allowDraggingOffscreen() || !ENABLE_MINIMIZE) {
-                    left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left));
-                }
-                if (mEnableDimissDragToEdge) {
-                    // Allow pip to move past bottom bounds
-                    top = Math.max(mMovementBounds.top, top);
-                } else {
-                    top = Math.max(mMovementBounds.top, Math.min(mMovementBounds.bottom, top));
-                }
 
                 // Add to the cumulative delta after bounding the position
                 mDelta.x += left - lastX;
@@ -720,8 +700,9 @@
                 if (mMotionHelper.shouldDismissPip() || isFlingToBot) {
                     MetricsLoggerWrapper.logPictureInPictureDismissByDrag(mContext,
                             PipUtils.getTopPinnedActivity(mContext, mActivityManager));
-                    mMotionHelper.animateDismiss(mMotionHelper.getBounds(), vel.x,
-                        vel.y, mUpdateScrimListener);
+                    mMotionHelper.animateDismiss(
+                            vel.x, vel.y,
+                            PipTouchHandler.this::updateDismissFraction /* updateAction */);
                     return true;
                 }
             }
@@ -739,8 +720,9 @@
                         // minimize offset adjusted
                         mMenuController.hideMenu();
                     } else {
-                        mMotionHelper.animateToClosestMinimizedState(mMovementBounds,
-                                mUpdateScrimListener);
+                        mMotionHelper.animateToClosestMinimizedState(
+                                mMovementBounds,
+                                PipTouchHandler.this::updateDismissFraction /* updateAction */);
                     }
                     return true;
                 }
@@ -750,7 +732,7 @@
                     setMinimizedStateInternal(false);
                 }
 
-                AnimatorListenerAdapter postAnimationCallback = null;
+                Runnable endAction = null;
                 if (mMenuState != MENU_STATE_NONE) {
                     // If the menu is still visible, and we aren't minimized, then just poke the
                     // menu so that it will timeout after the user stops touching it
@@ -759,26 +741,20 @@
                 } else {
                     // If the menu is not visible, then we can still be showing the activity for the
                     // dismiss overlay, so just finish it after the animation completes
-                    postAnimationCallback = new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            mMenuController.hideMenu();
-                        }
-                    };
+                    endAction = mMenuController::hideMenu;
                 }
 
                 if (isFling) {
-                    mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds,
-                            mUpdateScrimListener, postAnimationCallback,
-                            mStartPosition);
+                    mMotionHelper.flingToSnapTarget(
+                            vel.x, vel.y, mMovementBounds,
+                            PipTouchHandler.this::updateDismissFraction /* updateAction */,
+                            endAction /* endAction */);
                 } else {
-                    mMotionHelper.animateToClosestSnapTarget(mMovementBounds, mUpdateScrimListener,
-                            postAnimationCallback);
+                    mMotionHelper.animateToClosestSnapTarget(mMovementBounds);
                 }
             } else if (mIsMinimized) {
                 // This was a tap, so no longer minimized
-                mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* updateListener */,
-                        null /* animatorListener */);
+                mMotionHelper.animateToClosestSnapTarget(mMovementBounds);
                 setMinimizedStateInternal(false);
             } else if (mTouchState.isDoubleTap()) {
                 // Expand to fullscreen if this is a double tap
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index ae48db2..569f660 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -68,9 +68,9 @@
 import com.android.systemui.statusbar.phone.NavigationBarFragment;
 import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -109,7 +109,7 @@
     private SysUiState mSysUiState;
     private final Handler mHandler;
     private final NavigationBarController mNavBarController;
-    private final StatusBarWindowController mStatusBarWinController;
+    private final NotificationShadeWindowController mStatusBarWinController;
     private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
     private final ComponentName mRecentsComponentName;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -476,8 +476,9 @@
     @Inject
     public OverviewProxyService(Context context, DeviceProvisionedController provisionController,
             NavigationBarController navBarController, NavigationModeController navModeController,
-            StatusBarWindowController statusBarWinController, SysUiState sysUiState, PipUI pipUI,
-            Optional<Divider> dividerOptional, Optional<Lazy<StatusBar>> statusBarOptionalLazy) {
+            NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
+            PipUI pipUI, Optional<Divider> dividerOptional,
+            Optional<Lazy<StatusBar>> statusBarOptionalLazy) {
         mContext = context;
         mPipUI = pipUI;
         mStatusBarOptionalLazy = statusBarOptionalLazy;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 325af24..9fe6e84 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -332,6 +332,7 @@
             insets = state.calculateInsets(state.getDisplayFrame(), insets.isRound(),
                     insets.shouldAlwaysConsumeSystemBars(), insets.getDisplayCutout(),
                     null /* legacyContentInsets */, null /* legacyStableInsets */,
+                    0 /* legacySystemUiFlags */,
                     SOFT_INPUT_ADJUST_NOTHING, null /* typeSideMap */);
         }
         if (mStableInsets.left != insets.getStableInsetLeft()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 246b0f0..a457266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -59,10 +59,10 @@
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ScrimState;
 import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.io.FileDescriptor;
@@ -105,7 +105,7 @@
     private final NotificationEntryManager mEntryManager;
 
     @Nullable
-    private Lazy<StatusBarWindowController> mStatusBarWindowController;
+    private Lazy<NotificationShadeWindowController> mStatusBarWindowController;
 
     @Nullable
     private BiometricUnlockController mBiometricUnlockController;
@@ -180,7 +180,7 @@
     public NotificationMediaManager(
             Context context,
             Lazy<StatusBar> statusBarLazy,
-            Lazy<StatusBarWindowController> statusBarWindowController,
+            Lazy<NotificationShadeWindowController> statusBarWindowController,
             NotificationEntryManager notificationEntryManager,
             MediaArtworkProcessor mediaArtworkProcessor,
             KeyguardBypassController keyguardBypassController) {
@@ -525,7 +525,7 @@
             }
         }
 
-        StatusBarWindowController windowController = mStatusBarWindowController.get();
+        NotificationShadeWindowController windowController = mStatusBarWindowController.get();
         boolean hideBecauseOccluded = mStatusBarLazy.get().isOccluded();
 
         final boolean hasArtwork = artworkDrawable != null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
index 9398e6f..0ab5afa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
@@ -23,6 +23,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.util.InjectionInflationController;
 
@@ -30,8 +31,8 @@
 import javax.inject.Singleton;
 
 /**
- * Creates a single instance of super_status_bar that can be shared across various system ui
- * objects.
+ * Creates a single instance of super_status_bar and super_notification_shade that can be shared
+ * across various system ui objects.
  */
 @Singleton
 public class SuperStatusBarViewFactory {
@@ -39,6 +40,7 @@
     private final Context mContext;
     private final InjectionInflationController mInjectionInflationController;
 
+    private NotificationShadeWindowView mNotificationShadeWindowView;
     private StatusBarWindowView mStatusBarWindowView;
     private NotificationShelf mNotificationShelf;
 
@@ -50,15 +52,42 @@
     }
 
     /**
-     * Gets the inflated {@link StatusBarWindowView} from {@link R.layout#super_status_bar}. Returns
-     * a cached instance, if it has already been inflated.
+     * Gets the inflated {@link NotificationShadeWindowView} from
+     * {@link R.layout#super_notification_shade}.
+     * Returns a cached instance, if it has already been inflated.
+     */
+    public NotificationShadeWindowView getNotificationShadeWindowView() {
+        if (mNotificationShadeWindowView != null) {
+            return mNotificationShadeWindowView;
+        }
+
+        mNotificationShadeWindowView = (NotificationShadeWindowView)
+                mInjectionInflationController.injectable(
+                LayoutInflater.from(mContext)).inflate(R.layout.super_notification_shade,
+                /* root= */ null);
+        if (mNotificationShadeWindowView == null) {
+            throw new IllegalStateException(
+                    "R.layout.super_notification_shade could not be properly inflated");
+        }
+        return mNotificationShadeWindowView;
+    }
+
+    /** Gets the {@link LockIcon} inside of {@link R.layout#super_status_bar}. */
+    public LockIcon getLockIcon() {
+        return getNotificationShadeWindowView().findViewById(R.id.lock_icon);
+    }
+
+    /**
+     * Gets the inflated {@link StatusBarWindowView} from {@link R.layout#super_status_bar}.
+     * Returns a cached instance, if it has already been inflated.
      */
     public StatusBarWindowView getStatusBarWindowView() {
         if (mStatusBarWindowView != null) {
             return mStatusBarWindowView;
         }
 
-        mStatusBarWindowView = (StatusBarWindowView) mInjectionInflationController.injectable(
+        mStatusBarWindowView =
+                (StatusBarWindowView) mInjectionInflationController.injectable(
                 LayoutInflater.from(mContext)).inflate(R.layout.super_status_bar,
                 /* root= */ null);
         if (mStatusBarWindowView == null) {
@@ -68,11 +97,6 @@
         return mStatusBarWindowView;
     }
 
-    /** Gets the {@link LockIcon} inside of {@link R.layout#super_status_bar}. */
-    public LockIcon getLockIcon() {
-        return getStatusBarWindowView().findViewById(R.id.lock_icon);
-    }
-
     /**
      * Gets the inflated {@link NotificationShelf} from
      * {@link R.layout#status_bar_notification_shelf}.
@@ -98,11 +122,11 @@
     }
 
     public NotificationPanelView getNotificationPanelView() {
-        StatusBarWindowView statusBarWindowView = getStatusBarWindowView();
-        if (statusBarWindowView == null) {
+        NotificationShadeWindowView notificationShadeWindowView = getNotificationShadeWindowView();
+        if (notificationShadeWindowView == null) {
             return null;
         }
 
-        return mStatusBarWindowView.findViewById(R.id.notification_panel);
+        return mNotificationShadeWindowView.findViewById(R.id.notification_panel);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 6660569..5fc043a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -38,7 +38,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
 
 /**
  * A class that allows activities to be launched in a seamless way where the notification
@@ -56,7 +56,7 @@
     private final NotificationPanelViewController mNotificationPanel;
     private final NotificationListContainer mNotificationContainer;
     private final float mWindowCornerRadius;
-    private final StatusBarWindowViewController mStatusBarWindowViewController;
+    private final NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     private Callback mCallback;
     private final Runnable mTimeoutRunnable = () -> {
         setAnimationPending(false);
@@ -67,21 +67,23 @@
     private boolean mIsLaunchForActivity;
 
     public ActivityLaunchAnimator(
-            StatusBarWindowViewController statusBarWindowViewController,
+            NotificationShadeWindowViewController notificationShadeWindowViewController,
             Callback callback,
             NotificationPanelViewController notificationPanel,
             NotificationListContainer container) {
         mNotificationPanel = notificationPanel;
         mNotificationContainer = container;
-        mStatusBarWindowViewController = statusBarWindowViewController;
+        mNotificationShadeWindowViewController = notificationShadeWindowViewController;
         mCallback = callback;
         mWindowCornerRadius = ScreenDecorationsUtils
-                .getWindowCornerRadius(mStatusBarWindowViewController.getView().getResources());
+                .getWindowCornerRadius(mNotificationShadeWindowViewController.getView()
+                        .getResources());
     }
 
     public RemoteAnimationAdapter getLaunchAnimation(
             View sourceView, boolean occluded) {
-        if (!(sourceView instanceof ExpandableNotificationRow) || !mCallback.areLaunchAnimationsEnabled() || occluded) {
+        if (!(sourceView instanceof ExpandableNotificationRow)
+                || !mCallback.areLaunchAnimationsEnabled() || occluded) {
             return null;
         }
         AnimationRunner animationRunner = new AnimationRunner(
@@ -113,11 +115,12 @@
 
     private void setAnimationPending(boolean pending) {
         mAnimationPending = pending;
-        mStatusBarWindowViewController.setExpandAnimationPending(pending);
+        mNotificationShadeWindowViewController.setExpandAnimationPending(pending);
         if (pending) {
-            mStatusBarWindowViewController.getView().postDelayed(mTimeoutRunnable, LAUNCH_TIMEOUT);
+            mNotificationShadeWindowViewController.getView().postDelayed(mTimeoutRunnable,
+                    LAUNCH_TIMEOUT);
         } else {
-            mStatusBarWindowViewController.getView().removeCallbacks(mTimeoutRunnable);
+            mNotificationShadeWindowViewController.getView().removeCallbacks(mTimeoutRunnable);
         }
     }
 
@@ -247,7 +250,7 @@
         private void setExpandAnimationRunning(boolean running) {
             mNotificationPanel.setLaunchingNotification(running);
             mSourceNotification.setExpandAnimationRunning(running);
-            mStatusBarWindowViewController.setExpandAnimationRunning(running);
+            mNotificationShadeWindowViewController.setExpandAnimationRunning(running);
             mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null);
             mAnimationRunning = running;
             if (!running) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 6d3f3f4..64bdd97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION;
-import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
@@ -103,7 +102,6 @@
     private NotificationEntry mEntry;
     private StatusBarNotification mSbn;
     private boolean mIsDeviceProvisioned;
-
     private int mStartingChannelImportance;
     private boolean mStartedAsBubble;
     private boolean mIsBubbleable;
@@ -212,11 +210,10 @@
         mLauncherApps = launcherApps;
         mConversationId = mNotificationChannel.getConversationId();
         if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) {
-            mConversationId = mSbn.getNotification().getShortcutId();
+            mConversationId = mSbn.getShortcutId(mContext);
         }
-        // TODO: flag this when flag exists
         if (TextUtils.isEmpty(mConversationId)) {
-            mConversationId = mSbn.getId() + mSbn.getTag() + PLACEHOLDER_CONVERSATION_ID;
+            throw new IllegalArgumentException("Does not have required information");
         }
         // TODO: consider querying this earlier in the notification pipeline and passing it in
         LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery()
@@ -243,10 +240,9 @@
         // a custom channel
         if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) {
             try {
-                // TODO: associate this key with this channel service side so the customization
-                // isn't forgotten on the next update
                 mINotificationManager.createConversationNotificationChannelForPackage(
-                        mPackageName, mAppUid, mNotificationChannel, mConversationId);
+                        mPackageName, mAppUid, mSbn.getKey(), mNotificationChannel,
+                        mConversationId);
                 mNotificationChannel = mINotificationManager.getConversationNotificationChannel(
                         mContext.getOpPackageName(), UserHandle.getUserId(mAppUid), mPackageName,
                         mNotificationChannel.getId(), false, mConversationId);
@@ -363,7 +359,6 @@
             image.setImageDrawable(mLauncherApps.getShortcutBadgedIconDrawable(mShortcutInfo,
                     mContext.getResources().getDisplayMetrics().densityDpi));
         } else {
-            // TODO: flag this behavior
             if (mSbn.getNotification().extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION, false)) {
                 // TODO: maybe use a generic group icon, or a composite of recent senders
                 image.setImageDrawable(mPm.getDefaultActivityIcon());
@@ -391,7 +386,6 @@
         if (mShortcutInfo != null) {
             name.setText(mShortcutInfo.getShortLabel());
         } else {
-            // TODO: flag this behavior
             Bundle extras = mSbn.getNotification().extras;
             String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE);
             if (TextUtils.isEmpty(nameString)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 76fdfc6..874d81d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -47,7 +47,7 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.util.Utils;
 
 import java.util.Timer;
@@ -181,8 +181,9 @@
             final int[] compactActions = mRow.getEntry().getSbn().getNotification().extras
                     .getIntArray(Notification.EXTRA_COMPACT_ACTIONS);
             int tintColor = getNotificationHeader().getOriginalIconColor();
-            StatusBarWindowController ctrl = Dependency.get(StatusBarWindowController.class);
-            QuickQSPanel panel = ctrl.getStatusBarView().findViewById(
+            NotificationShadeWindowController ctrl = Dependency.get(
+                    NotificationShadeWindowController.class);
+            QuickQSPanel panel = ctrl.getNotificationShadeView().findViewById(
                     com.android.systemui.R.id.quick_qs_panel);
             StatusBarNotification sbn = mRow.getEntry().getSbn();
             Notification notif = sbn.getNotification();
@@ -193,7 +194,7 @@
                     mActions,
                     compactActions,
                     notif.contentIntent);
-            QSPanel bigPanel = ctrl.getStatusBarView().findViewById(
+            QSPanel bigPanel = ctrl.getNotificationShadeView().findViewById(
                     com.android.systemui.R.id.quick_settings_panel);
             bigPanel.addMediaSession(token,
                     notif.getSmallIcon(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 4880520..691e1c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -141,7 +141,7 @@
     private final KeyguardUpdateMonitor mUpdateMonitor;
     private final DozeParameters mDozeParameters;
     private final KeyguardStateController mKeyguardStateController;
-    private final StatusBarWindowController mStatusBarWindowController;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final Context mContext;
     private final int mWakeUpDelay;
     private int mMode;
@@ -162,7 +162,7 @@
     public BiometricUnlockController(Context context, DozeScrimController dozeScrimController,
             KeyguardViewMediator keyguardViewMediator, ScrimController scrimController,
             StatusBar statusBar, ShadeController shadeController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController, Handler handler,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             @Main Resources resources,
@@ -177,7 +177,8 @@
         mMediaManager = Dependency.get(NotificationMediaManager.class);
         Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
         Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
-        mStatusBarWindowController = statusBarWindowController;
+
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mDozeScrimController = dozeScrimController;
         mKeyguardViewMediator = keyguardViewMediator;
         mScrimController = scrimController;
@@ -284,7 +285,7 @@
             // notifications would light up first, creating an unpleasant animation.
             // Defer changing the screen brightness by forcing doze brightness on our window
             // until the clock and the notifications are faded out.
-            mStatusBarWindowController.setForceDozeBrightness(true);
+            mNotificationShadeWindowController.setForceDozeBrightness(true);
         }
         // During wake and unlock, we need to draw black before waking up to avoid abrupt
         // brightness changes due to display state transitions.
@@ -340,7 +341,7 @@
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
                     mUpdateMonitor.awakenFromDream();
                 }
-                mStatusBarWindowController.setStatusBarFocusable(false);
+                mNotificationShadeWindowController.setNotificationShadeFocusable(false);
                 if (delayWakeUp) {
                     mHandler.postDelayed(wakeUp, mWakeUpDelay);
                 } else {
@@ -508,7 +509,7 @@
         mHandler.postDelayed(new Runnable() {
             @Override
             public void run() {
-                mStatusBarWindowController.setForceDozeBrightness(false);
+                mNotificationShadeWindowController.setForceDozeBrightness(false);
             }
         }, StatusBar.FADE_KEYGUARD_DURATION_PULSING);
     }
@@ -522,7 +523,7 @@
 
     private void resetMode() {
         mMode = MODE_NONE;
-        mStatusBarWindowController.setForceDozeBrightness(false);
+        mNotificationShadeWindowController.setForceDozeBrightness(false);
         if (mStatusBar.getNavigationBarView() != null) {
             mStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index accd2a4..04efc2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -85,9 +85,9 @@
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final VisualStabilityManager mVisualStabilityManager;
     private final PulseExpansionHandler mPulseExpansionHandler;
-    private final StatusBarWindowController mStatusBarWindowController;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
-    private StatusBarWindowViewController mStatusBarWindowViewController;
+    private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     private final LockscreenLockIconController mLockscreenLockIconController;
     private NotificationIconAreaController mNotificationIconAreaController;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -108,7 +108,7 @@
             DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor,
             VisualStabilityManager visualStabilityManager,
             PulseExpansionHandler pulseExpansionHandler,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             LockscreenLockIconController lockscreenLockIconController) {
         super();
@@ -127,7 +127,7 @@
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mVisualStabilityManager = visualStabilityManager;
         mPulseExpansionHandler = pulseExpansionHandler;
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
         mLockscreenLockIconController = lockscreenLockIconController;
     }
@@ -140,13 +140,13 @@
     public void initialize(StatusBar statusBar,
             NotificationIconAreaController notificationIconAreaController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            StatusBarWindowViewController statusBarWindowViewController,
+            NotificationShadeWindowViewController notificationShadeWindowViewController,
             NotificationPanelViewController notificationPanel, View ambientIndicationContainer) {
         mStatusBar = statusBar;
         mNotificationIconAreaController = notificationIconAreaController;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mNotificationPanel = notificationPanel;
-        mStatusBarWindowViewController = statusBarWindowViewController;
+        mNotificationShadeWindowViewController = notificationShadeWindowViewController;
         mAmbientIndicationContainer = ambientIndicationContainer;
         mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
     }
@@ -292,7 +292,7 @@
         }
         mIgnoreTouchWhilePulsing = ignore;
         if (mStatusBarStateController.isDozing() && ignore) {
-            mStatusBarWindowViewController.cancelCurrentTouch();
+            mNotificationShadeWindowViewController.cancelCurrentTouch();
         }
     }
 
@@ -391,7 +391,7 @@
 
     @Override
     public void setDozeScreenBrightness(int value) {
-        mStatusBarWindowController.setDozeScreenBrightness(value);
+        mNotificationShadeWindowController.setDozeScreenBrightness(value);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 7b20a7b..c39ee3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -92,21 +92,22 @@
 
     public HeadsUpAppearanceController(
             NotificationIconAreaController notificationIconAreaController,
-            HeadsUpManagerPhone headsUpManager, View statusbarView,
+            HeadsUpManagerPhone headsUpManager,
+            View notificationShadeView,
             SysuiStatusBarStateController statusBarStateController,
             KeyguardBypassController keyguardBypassController,
             KeyguardStateController keyguardStateController,
             NotificationWakeUpCoordinator wakeUpCoordinator, CommandQueue commandQueue,
-            NotificationPanelViewController notificationPanelViewController) {
+            NotificationPanelViewController notificationPanelViewController, View statusBarView) {
         this(notificationIconAreaController, headsUpManager, statusBarStateController,
                 keyguardBypassController, wakeUpCoordinator, keyguardStateController,
                 commandQueue,
-                statusbarView.findViewById(R.id.heads_up_status_bar_view),
-                statusbarView.findViewById(R.id.notification_stack_scroller),
+                statusBarView.findViewById(R.id.heads_up_status_bar_view),
+                notificationShadeView.findViewById(R.id.notification_stack_scroller),
                 notificationPanelViewController,
-                statusbarView.findViewById(R.id.clock),
-                statusbarView.findViewById(R.id.operator_name_frame),
-                statusbarView.findViewById(R.id.centered_icon_area));
+                statusBarView.findViewById(R.id.clock),
+                statusBarView.findViewById(R.id.operator_name_frame),
+                statusBarView.findViewById(R.id.centered_icon_area));
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 6ac6d35..c6e3fde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -65,7 +65,7 @@
     private final StatusBarStateController mStatusBarStateController;
     private final KeyguardBypassController mBypassController;
     private final int mAutoHeadsUpNotificationDecay;
-    private View mStatusBarWindowView;
+    private View mNotificationShadeWindowView;
     private NotificationGroupManager mGroupManager;
     private VisualStabilityManager mVisualStabilityManager;
     private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
@@ -124,14 +124,13 @@
         initResources();
     }
 
-
-    public void setUp(@NonNull View statusBarWindowView,
+    public void setUp(@NonNull View notificationShadeWindowView,
             @NonNull NotificationGroupManager groupManager,
             @NonNull StatusBar bar,
             @NonNull VisualStabilityManager visualStabilityManager) {
-        mStatusBarWindowView = statusBarWindowView;
-        mStatusBarTouchableRegionManager = new StatusBarTouchableRegionManager(mContext, this, bar,
-                statusBarWindowView);
+        mNotificationShadeWindowView = notificationShadeWindowView;
+        mStatusBarTouchableRegionManager = new StatusBarTouchableRegionManager(this, bar,
+                notificationShadeWindowView);
         mGroupManager = groupManager;
         mVisualStabilityManager = visualStabilityManager;
 
@@ -364,7 +363,7 @@
         // updated yet, but callbacks leading out of the headsUp manager, querying it. Let's
         // therefore also check if the topEntry is null.
         if (!hasPinnedHeadsUp() || topEntry == null) {
-            mTouchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
+            mTouchableRegion.set(0, 0, mNotificationShadeWindowView.getWidth(), mStatusBarHeight);
             updateRegionForNotch(mTouchableRegion);
 
         } else {
@@ -386,7 +385,7 @@
     }
 
     private void updateRegionForNotch(Region region) {
-        WindowInsets windowInsets = mStatusBarWindowView.getRootWindowInsets();
+        WindowInsets windowInsets = mNotificationShadeWindowView.getRootWindowInsets();
         if (windowInsets == null) {
             Log.w(TAG, "StatusBarWindowView is not attached.");
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 3554b54..707138e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -128,7 +128,7 @@
             mAodIcons.setAnimationsEnabled(false);
             mAodIcons.removeAllViews();
         }
-        mAodIcons = mStatusBar.getStatusBarWindow().findViewById(
+        mAodIcons = mStatusBar.getNotificationShadeWindowView().findViewById(
                 R.id.clock_notification_icon_container);
         mAodIcons.setOnLockScreen(true);
         updateAodIconsVisibility(false /* animate */);
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 90ec2a0..6112ae8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1367,14 +1367,7 @@
         if (mExpectingSynthesizedDown) {
             mExpectingSynthesizedDown = false;
             maybeVibrateOnOpening();
-            Runnable runnable = () -> fling(velocity > 1f ? 1000f * velocity : 0,
-                    true /* expand */);
-            if (mStatusBar.getStatusBarWindow().getHeight() != mStatusBar.getStatusBarHeight()) {
-                // The panel is already expanded to its full size, let's expand directly
-                runnable.run();
-            } else {
-                mExpandAfterLayoutRunnable = runnable;
-            }
+            fling(velocity > 1f ? 1000f * velocity : 0, true /* expand */);
             onTrackingStopped(false);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
new file mode 100644
index 0000000..fe4879b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
+
+import android.app.IActivityManager;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.util.Log;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+
+import com.android.systemui.Dumpable;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.statusbar.RemoteInputController.Callback;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SuperStatusBarViewFactory;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+
+import com.google.android.collect.Lists;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Encapsulates all logic for the notification shade window state management.
+ */
+@Singleton
+public class NotificationShadeWindowController implements Callback, Dumpable,
+        ConfigurationListener {
+
+    private static final String TAG = "NotificationShadeWindowController";
+    private static final boolean DEBUG = false;
+
+    private final Context mContext;
+    private final WindowManager mWindowManager;
+    private final IActivityManager mActivityManager;
+    private final DozeParameters mDozeParameters;
+    private final LayoutParams mLpChanged;
+    private final boolean mKeyguardScreenRotation;
+    private final long mLockScreenDisplayTimeout;
+    private final Display.Mode mKeyguardDisplayMode;
+    private final KeyguardBypassController mKeyguardBypassController;
+    private ViewGroup mNotificationShadeView;
+    private LayoutParams mLp;
+    private boolean mHasTopUi;
+    private boolean mHasTopUiChanged;
+    private float mScreenBrightnessDoze;
+    private final State mCurrentState = new State();
+    private OtherwisedCollapsedListener mListener;
+    private ForcePluginOpenListener mForcePluginOpenListener;
+    private final ArrayList<WeakReference<StatusBarWindowCallback>>
+            mCallbacks = Lists.newArrayList();
+
+    private final SysuiColorExtractor mColorExtractor;
+    private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+
+    @Inject
+    public NotificationShadeWindowController(Context context, WindowManager windowManager,
+            IActivityManager activityManager, DozeParameters dozeParameters,
+            StatusBarStateController statusBarStateController,
+            ConfigurationController configurationController,
+            KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor,
+            SuperStatusBarViewFactory superStatusBarViewFactory) {
+        mContext = context;
+        mWindowManager = windowManager;
+        mActivityManager = activityManager;
+        mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
+        mDozeParameters = dozeParameters;
+        mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
+        mLpChanged = new LayoutParams();
+        mKeyguardBypassController = keyguardBypassController;
+        mColorExtractor = colorExtractor;
+        mSuperStatusBarViewFactory = superStatusBarViewFactory;
+        mNotificationShadeView = mSuperStatusBarViewFactory.getNotificationShadeWindowView();
+
+        mLockScreenDisplayTimeout = context.getResources()
+                .getInteger(R.integer.config_lockScreenDisplayTimeout);
+        ((SysuiStatusBarStateController) statusBarStateController)
+                .addCallback(mStateListener,
+                        SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
+        configurationController.addCallback(this);
+
+        Display.Mode[] supportedModes = context.getDisplay().getSupportedModes();
+        Display.Mode currentMode = context.getDisplay().getMode();
+        // Running on the highest frame rate available can be expensive.
+        // Let's specify a preferred refresh rate, and allow higher FPS only when we
+        // know that we're not falsing (because we unlocked.)
+        int keyguardRefreshRate = context.getResources()
+                .getInteger(R.integer.config_keyguardRefreshRate);
+        // Find supported display mode with the same resolution and requested refresh rate.
+        mKeyguardDisplayMode = Arrays.stream(supportedModes).filter(mode ->
+                (int) mode.getRefreshRate() == keyguardRefreshRate
+                        && mode.getPhysicalWidth() == currentMode.getPhysicalWidth()
+                        && mode.getPhysicalHeight() == currentMode.getPhysicalHeight())
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Register to receive notifications about status bar window state changes.
+     */
+    public void registerCallback(StatusBarWindowCallback callback) {
+        // Prevent adding duplicate callbacks
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            if (mCallbacks.get(i).get() == callback) {
+                return;
+            }
+        }
+        mCallbacks.add(new WeakReference<StatusBarWindowCallback>(callback));
+    }
+
+    private boolean shouldEnableKeyguardScreenRotation() {
+        Resources res = mContext.getResources();
+        return SystemProperties.getBoolean("lockscreen.rot_override", false)
+                || res.getBoolean(R.bool.config_enableLockScreenRotation);
+    }
+
+    /**
+     * Adds the notification shade view to the window manager.
+     */
+    public void attach() {
+        // Now that the notification shade encompasses the sliding panel and its
+        // translucent backdrop, the entire thing is made TRANSLUCENT and is
+        // hardware-accelerated.
+        mLp = new LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                LayoutParams.TYPE_NOTIFICATION_SHADE,
+                LayoutParams.FLAG_NOT_FOCUSABLE
+                        | LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+                        | LayoutParams.FLAG_SPLIT_TOUCH
+                        | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                        | LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                PixelFormat.TRANSLUCENT);
+        mLp.token = new Binder();
+        mLp.gravity = Gravity.TOP;
+        mLp.setFitWindowInsetsTypes(0 /* types */);
+        mLp.softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+        mLp.setTitle("NotificationShade");
+        mLp.packageName = mContext.getPackageName();
+        mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        mWindowManager.addView(mNotificationShadeView, mLp);
+        mLpChanged.copyFrom(mLp);
+        onThemeChanged();
+    }
+
+    public ViewGroup getNotificationShadeView() {
+        return mNotificationShadeView;
+    }
+
+    public void setDozeScreenBrightness(int value) {
+        mScreenBrightnessDoze = value / 255f;
+    }
+
+    private void setKeyguardDark(boolean dark) {
+        int vis = mNotificationShadeView.getSystemUiVisibility();
+        if (dark) {
+            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else {
+            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        }
+        mNotificationShadeView.setSystemUiVisibility(vis);
+    }
+
+    private void applyKeyguardFlags(State state) {
+        final boolean scrimsOccludingWallpaper =
+                state.mScrimsVisibility == ScrimController.OPAQUE;
+        final boolean keyguardOrAod = state.mKeyguardShowing
+                || (state.mDozing && mDozeParameters.getAlwaysOn());
+        if (keyguardOrAod && !state.mBackdropShowing && !scrimsOccludingWallpaper) {
+            mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;
+        } else {
+            mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;
+        }
+
+        if (state.mDozing) {
+            mLpChanged.privateFlags |= LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+        } else {
+            mLpChanged.privateFlags &= ~LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+        }
+
+        if (mKeyguardDisplayMode != null) {
+            boolean bypassOnKeyguard = mKeyguardBypassController.getBypassEnabled()
+                    && state.mStatusBarState == StatusBarState.KEYGUARD
+                    && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway;
+            if (state.mDozing || bypassOnKeyguard) {
+                mLpChanged.preferredDisplayModeId = mKeyguardDisplayMode.getModeId();
+            } else {
+                mLpChanged.preferredDisplayModeId = 0;
+            }
+            Trace.setCounter("display_mode_id", mLpChanged.preferredDisplayModeId);
+        }
+    }
+
+    private void adjustScreenOrientation(State state) {
+        if (state.isKeyguardShowingAndNotOccluded() || state.mDozing) {
+            if (mKeyguardScreenRotation) {
+                mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
+            } else {
+                mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+            }
+        } else {
+            mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+        }
+    }
+
+    private void applyFocusableFlag(State state) {
+        boolean panelFocusable = state.mNotificationShadeFocusable && state.mPanelExpanded;
+        if (state.mBouncerShowing && (state.mKeyguardOccluded || state.mKeyguardNeedsInput)
+                || ENABLE_REMOTE_INPUT && state.mRemoteInputActive
+                || state.mBubbleExpanded) {
+            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
+            mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
+            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
+            // Make sure to remove FLAG_ALT_FOCUSABLE_IM when keyguard needs input.
+            if (state.mKeyguardNeedsInput) {
+                mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            } else {
+                mLpChanged.flags |= LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            }
+        } else {
+            mLpChanged.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
+            mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        }
+
+        mLpChanged.softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+    }
+
+    private void applyForceShowNavigationFlag(State state) {
+        if (state.mPanelExpanded || state.mBouncerShowing
+                || ENABLE_REMOTE_INPUT && state.mRemoteInputActive) {
+            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+        } else {
+            mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+        }
+    }
+
+    private void applyVisibility(State state) {
+        boolean visible = isExpanded(state);
+        if (state.mForcePluginOpen) {
+            if (mListener != null) {
+                mListener.setWouldOtherwiseCollapse(visible);
+            }
+            visible = true;
+        }
+        if (visible) {
+            mNotificationShadeView.setVisibility(View.VISIBLE);
+        } else {
+            mNotificationShadeView.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    private boolean isExpanded(State state) {
+        return !state.mForceCollapsed && (state.isKeyguardShowingAndNotOccluded()
+                || state.mPanelVisible || state.mKeyguardFadingAway || state.mBouncerShowing
+                || state.mHeadsUpShowing || state.mBubblesShowing
+                || state.mScrimsVisibility != ScrimController.TRANSPARENT);
+    }
+
+    private void applyFitsSystemWindows(State state) {
+        boolean fitsSystemWindows = !state.isKeyguardShowingAndNotOccluded();
+        if (mNotificationShadeView != null
+                && mNotificationShadeView.getFitsSystemWindows() != fitsSystemWindows) {
+            mNotificationShadeView.setFitsSystemWindows(fitsSystemWindows);
+            mNotificationShadeView.requestApplyInsets();
+        }
+    }
+
+    private void applyUserActivityTimeout(State state) {
+        if (state.isKeyguardShowingAndNotOccluded()
+                && state.mStatusBarState == StatusBarState.KEYGUARD
+                && !state.mQsExpanded) {
+            mLpChanged.userActivityTimeout = state.mBouncerShowing
+                    ? KeyguardViewMediator.AWAKE_INTERVAL_BOUNCER_MS : mLockScreenDisplayTimeout;
+        } else {
+            mLpChanged.userActivityTimeout = -1;
+        }
+    }
+
+    private void applyInputFeatures(State state) {
+        if (state.isKeyguardShowingAndNotOccluded()
+                && state.mStatusBarState == StatusBarState.KEYGUARD
+                && !state.mQsExpanded && !state.mForceUserActivity) {
+            mLpChanged.inputFeatures |=
+                    LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+        } else {
+            mLpChanged.inputFeatures &=
+                    ~LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+        }
+    }
+
+    private void applyStatusBarColorSpaceAgnosticFlag(State state) {
+        if (!isExpanded(state)) {
+            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+        } else {
+            mLpChanged.privateFlags &=
+                    ~LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+        }
+    }
+
+    private void apply(State state) {
+        applyKeyguardFlags(state);
+        applyFocusableFlag(state);
+        applyForceShowNavigationFlag(state);
+        adjustScreenOrientation(state);
+        applyVisibility(state);
+        applyUserActivityTimeout(state);
+        applyInputFeatures(state);
+        applyFitsSystemWindows(state);
+        applyModalFlag(state);
+        applyBrightness(state);
+        applyHasTopUi(state);
+        applyNotTouchable(state);
+        applyStatusBarColorSpaceAgnosticFlag(state);
+        if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
+            mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
+        }
+        if (mHasTopUi != mHasTopUiChanged) {
+            whitelistIpcs(() -> {
+                try {
+                    mActivityManager.setHasTopUi(mHasTopUiChanged);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to call setHasTopUi", e);
+                }
+                mHasTopUi = mHasTopUiChanged;
+            });
+        }
+        notifyStateChangedCallbacks();
+    }
+
+    public void notifyStateChangedCallbacks() {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            StatusBarWindowCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onStateChanged(mCurrentState.mKeyguardShowing,
+                        mCurrentState.mKeyguardOccluded,
+                        mCurrentState.mBouncerShowing);
+            }
+        }
+    }
+
+    private void applyModalFlag(State state) {
+        if (state.mHeadsUpShowing) {
+            mLpChanged.flags |= LayoutParams.FLAG_NOT_TOUCH_MODAL;
+        } else {
+            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_TOUCH_MODAL;
+        }
+    }
+
+    private void applyBrightness(State state) {
+        if (state.mForceDozeBrightness) {
+            mLpChanged.screenBrightness = mScreenBrightnessDoze;
+        } else {
+            mLpChanged.screenBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
+        }
+    }
+
+    private void applyHasTopUi(State state) {
+        mHasTopUiChanged = state.mForceHasTopUi || isExpanded(state);
+    }
+
+    private void applyNotTouchable(State state) {
+        if (state.mNotTouchable) {
+            mLpChanged.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
+        } else {
+            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_TOUCHABLE;
+        }
+    }
+
+    public void setKeyguardShowing(boolean showing) {
+        mCurrentState.mKeyguardShowing = showing;
+        apply(mCurrentState);
+    }
+
+    public void setKeyguardOccluded(boolean occluded) {
+        mCurrentState.mKeyguardOccluded = occluded;
+        apply(mCurrentState);
+    }
+
+    public void setKeyguardNeedsInput(boolean needsInput) {
+        mCurrentState.mKeyguardNeedsInput = needsInput;
+        apply(mCurrentState);
+    }
+
+    public void setPanelVisible(boolean visible) {
+        mCurrentState.mPanelVisible = visible;
+        mCurrentState.mNotificationShadeFocusable = visible;
+        apply(mCurrentState);
+    }
+
+    public void setNotificationShadeFocusable(boolean focusable) {
+        mCurrentState.mNotificationShadeFocusable = focusable;
+        apply(mCurrentState);
+    }
+
+    public void setBouncerShowing(boolean showing) {
+        mCurrentState.mBouncerShowing = showing;
+        apply(mCurrentState);
+    }
+
+    public void setBackdropShowing(boolean showing) {
+        mCurrentState.mBackdropShowing = showing;
+        apply(mCurrentState);
+    }
+
+    public void setKeyguardFadingAway(boolean keyguardFadingAway) {
+        mCurrentState.mKeyguardFadingAway = keyguardFadingAway;
+        apply(mCurrentState);
+    }
+
+    public void setQsExpanded(boolean expanded) {
+        mCurrentState.mQsExpanded = expanded;
+        apply(mCurrentState);
+    }
+
+    public void setForceUserActivity(boolean forceUserActivity) {
+        mCurrentState.mForceUserActivity = forceUserActivity;
+        apply(mCurrentState);
+    }
+
+    public void setScrimsVisibility(int scrimsVisibility) {
+        mCurrentState.mScrimsVisibility = scrimsVisibility;
+        apply(mCurrentState);
+    }
+
+    public void setHeadsUpShowing(boolean showing) {
+        mCurrentState.mHeadsUpShowing = showing;
+        apply(mCurrentState);
+    }
+
+    public void setWallpaperSupportsAmbientMode(boolean supportsAmbientMode) {
+        mCurrentState.mWallpaperSupportsAmbientMode = supportsAmbientMode;
+        apply(mCurrentState);
+    }
+
+    /**
+     * @param state The {@link StatusBarStateController} of the status bar.
+     */
+    private void setStatusBarState(int state) {
+        mCurrentState.mStatusBarState = state;
+        apply(mCurrentState);
+    }
+
+    /**
+     * Force the window to be collapsed, even if it should theoretically be expanded.
+     * Used for when a heads-up comes in but we still need to wait for the touchable regions to
+     * be computed.
+     */
+    public void setForceWindowCollapsed(boolean force) {
+        mCurrentState.mForceCollapsed = force;
+        apply(mCurrentState);
+    }
+
+    public void setPanelExpanded(boolean isExpanded) {
+        mCurrentState.mPanelExpanded = isExpanded;
+        apply(mCurrentState);
+    }
+
+    @Override
+    public void onRemoteInputActive(boolean remoteInputActive) {
+        mCurrentState.mRemoteInputActive = remoteInputActive;
+        apply(mCurrentState);
+    }
+
+    /**
+     * Set whether the screen brightness is forced to the value we use for doze mode by the status
+     * bar window.
+     */
+    public void setForceDozeBrightness(boolean forceDozeBrightness) {
+        mCurrentState.mForceDozeBrightness = forceDozeBrightness;
+        apply(mCurrentState);
+    }
+
+    public void setDozing(boolean dozing) {
+        mCurrentState.mDozing = dozing;
+        apply(mCurrentState);
+    }
+
+    public void setForcePluginOpen(boolean forcePluginOpen) {
+        mCurrentState.mForcePluginOpen = forcePluginOpen;
+        apply(mCurrentState);
+        if (mForcePluginOpenListener != null) {
+            mForcePluginOpenListener.onChange(forcePluginOpen);
+        }
+    }
+
+    /**
+     * The forcePluginOpen state for the status bar.
+     */
+    public boolean getForcePluginOpen() {
+        return mCurrentState.mForcePluginOpen;
+    }
+
+    public void setNotTouchable(boolean notTouchable) {
+        mCurrentState.mNotTouchable = notTouchable;
+        apply(mCurrentState);
+    }
+
+    /**
+     * Sets whether there are bubbles showing on the screen.
+     */
+    public void setBubblesShowing(boolean bubblesShowing) {
+        mCurrentState.mBubblesShowing = bubblesShowing;
+        apply(mCurrentState);
+    }
+
+    /**
+     * The bubbles showing state for the status bar.
+     */
+    public boolean getBubblesShowing() {
+        return mCurrentState.mBubblesShowing;
+    }
+
+    /**
+     * Sets if there is a bubble being expanded on the screen.
+     */
+    public void setBubbleExpanded(boolean bubbleExpanded) {
+        mCurrentState.mBubbleExpanded = bubbleExpanded;
+        apply(mCurrentState);
+    }
+
+    /**
+     * Whether the bubble is shown in expanded state for the status bar.
+     */
+    public boolean getBubbleExpanded() {
+        return mCurrentState.mBubbleExpanded;
+    }
+
+    /**
+     * Whether the status bar panel is expanded or not.
+     */
+    public boolean getPanelExpanded() {
+        return mCurrentState.mPanelExpanded;
+    }
+
+    public void setStateListener(OtherwisedCollapsedListener listener) {
+        mListener = listener;
+    }
+
+    public void setForcePluginOpenListener(ForcePluginOpenListener listener) {
+        mForcePluginOpenListener = listener;
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("StatusBarWindowController:");
+        pw.println("  mKeyguardDisplayMode=" + mKeyguardDisplayMode);
+        pw.println(mCurrentState);
+    }
+
+    public boolean isShowingWallpaper() {
+        return !mCurrentState.mBackdropShowing;
+    }
+
+    @Override
+    public void onThemeChanged() {
+        if (mNotificationShadeView == null) {
+            return;
+        }
+
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
+        // Make sure we have the correct navbar/statusbar colors.
+        setKeyguardDark(useDarkText);
+    }
+
+    /**
+     * When keyguard will be dismissed but didn't start animation yet.
+     */
+    public void setKeyguardGoingAway(boolean goingAway) {
+        mCurrentState.mKeyguardGoingAway = goingAway;
+        apply(mCurrentState);
+    }
+
+    public boolean getForceHasTopUi() {
+        return mCurrentState.mForceHasTopUi;
+    }
+
+    public void setForceHasTopUi(boolean forceHasTopUi) {
+        mCurrentState.mForceHasTopUi = forceHasTopUi;
+        apply(mCurrentState);
+    }
+
+    private static class State {
+        boolean mKeyguardShowing;
+        boolean mKeyguardOccluded;
+        boolean mKeyguardNeedsInput;
+        boolean mPanelVisible;
+        boolean mPanelExpanded;
+        boolean mNotificationShadeFocusable;
+        boolean mBouncerShowing;
+        boolean mKeyguardFadingAway;
+        boolean mKeyguardGoingAway;
+        boolean mQsExpanded;
+        boolean mHeadsUpShowing;
+        boolean mForceCollapsed;
+        boolean mForceDozeBrightness;
+        boolean mForceUserActivity;
+        boolean mBackdropShowing;
+        boolean mWallpaperSupportsAmbientMode;
+        boolean mNotTouchable;
+        boolean mBubblesShowing;
+        boolean mBubbleExpanded;
+        boolean mForceHasTopUi;
+
+        /**
+         * The {@link StatusBar} state from the status bar.
+         */
+        int mStatusBarState;
+
+        boolean mRemoteInputActive;
+        boolean mForcePluginOpen;
+        boolean mDozing;
+        int mScrimsVisibility;
+
+        private boolean isKeyguardShowingAndNotOccluded() {
+            return mKeyguardShowing && !mKeyguardOccluded;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder result = new StringBuilder();
+            String newLine = "\n";
+            result.append("Window State {");
+            result.append(newLine);
+
+            Field[] fields = this.getClass().getDeclaredFields();
+
+            // Print field names paired with their values
+            for (Field field : fields) {
+                result.append("  ");
+                try {
+                    result.append(field.getName());
+                    result.append(": ");
+                    //requires access to private field:
+                    result.append(field.get(this));
+                } catch (IllegalAccessException ex) {
+                }
+                result.append(newLine);
+            }
+            result.append("}");
+
+            return result.toString();
+        }
+    }
+
+    private final StateListener mStateListener = new StateListener() {
+        @Override
+        public void onStateChanged(int newState) {
+            setStatusBarState(newState);
+        }
+
+        @Override
+        public void onDozingChanged(boolean isDozing) {
+            setDozing(isDozing);
+        }
+    };
+
+    /**
+     * Custom listener to pipe data back to plugins about whether or not the status bar would be
+     * collapsed if not for the plugin.
+     * TODO: Find cleaner way to do this.
+     */
+    public interface OtherwisedCollapsedListener {
+        void setWouldOtherwiseCollapse(boolean otherwiseCollapse);
+    }
+
+    /**
+     * Listener to indicate forcePluginOpen has changed
+     */
+    public interface ForcePluginOpenListener {
+        /**
+         * Called when mState.forcePluginOpen is changed
+         */
+        void onChange(boolean forceOpen);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
new file mode 100644
index 0000000..6979554
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
@@ -0,0 +1,614 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.LayoutRes;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Insets;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.ActionMode;
+import android.view.DisplayCutout;
+import android.view.InputQueue;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
+import android.widget.FrameLayout;
+
+import com.android.internal.view.FloatingActionMode;
+import com.android.internal.widget.FloatingToolbar;
+import com.android.systemui.R;
+
+/**
+ * Combined keyguard and notification panel view. Also holding backdrop and scrims.
+ */
+public class NotificationShadeWindowView extends FrameLayout {
+    public static final String TAG = "NotificationShadeWindowView";
+    public static final boolean DEBUG = StatusBar.DEBUG;
+
+    private int mRightInset = 0;
+    private int mLeftInset = 0;
+
+    // Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
+    // DecorView, but since this is a special window we have to roll our own.
+    private View mFloatingActionModeOriginatingView;
+    private ActionMode mFloatingActionMode;
+    private FloatingToolbar mFloatingToolbar;
+    private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
+
+    private InteractionEventHandler mInteractionEventHandler;
+
+    public NotificationShadeWindowView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setMotionEventSplittingEnabled(false);
+    }
+
+    public NotificationPanelView getNotificationPanelView() {
+        return findViewById(R.id.notification_panel);
+    }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
+        final Insets insets = windowInsets.getMaxInsets(WindowInsets.Type.systemBars());
+        if (getFitsSystemWindows()) {
+            boolean paddingChanged = insets.top != getPaddingTop()
+                    || insets.bottom != getPaddingBottom();
+
+            int rightCutout = 0;
+            int leftCutout = 0;
+            DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
+            if (displayCutout != null) {
+                leftCutout = displayCutout.getSafeInsetLeft();
+                rightCutout = displayCutout.getSafeInsetRight();
+            }
+
+            int targetLeft = Math.max(insets.left, leftCutout);
+            int targetRight = Math.max(insets.right, rightCutout);
+
+            // Super-special right inset handling, because scrims and backdrop need to ignore it.
+            if (targetRight != mRightInset || targetLeft != mLeftInset) {
+                mRightInset = targetRight;
+                mLeftInset = targetLeft;
+                applyMargins();
+            }
+            // Drop top inset, and pass through bottom inset.
+            if (paddingChanged) {
+                setPadding(0, 0, 0, 0);
+            }
+        } else {
+            if (mRightInset != 0 || mLeftInset != 0) {
+                mRightInset = 0;
+                mLeftInset = 0;
+                applyMargins();
+            }
+            boolean changed = getPaddingLeft() != 0
+                    || getPaddingRight() != 0
+                    || getPaddingTop() != 0
+                    || getPaddingBottom() != 0;
+            if (changed) {
+                setPadding(0, 0, 0, 0);
+            }
+        }
+        return windowInsets;
+    }
+
+    private void applyMargins() {
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            if (child.getLayoutParams() instanceof LayoutParams) {
+                LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                if (!lp.ignoreRightInset
+                        && (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset)) {
+                    lp.rightMargin = mRightInset;
+                    lp.leftMargin = mLeftInset;
+                    child.requestLayout();
+                }
+            }
+        }
+    }
+
+    @Override
+    public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected FrameLayout.LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        setWillNotDraw(!DEBUG);
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (mInteractionEventHandler.interceptMediaKey(event)) {
+            return true;
+        }
+
+        if (super.dispatchKeyEvent(event)) {
+            return true;
+        }
+
+        return mInteractionEventHandler.dispatchKeyEvent(event);
+    }
+
+    protected void setInteractionEventHandler(InteractionEventHandler listener) {
+        mInteractionEventHandler = listener;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        Boolean result = mInteractionEventHandler.handleDispatchTouchEvent(ev);
+
+        return result != null ? result : super.dispatchTouchEvent(ev);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        boolean intercept = mInteractionEventHandler.shouldInterceptTouchEvent(ev);
+        if (!intercept) {
+            intercept = super.onInterceptTouchEvent(ev);
+        }
+        if (intercept) {
+            mInteractionEventHandler.didIntercept(ev);
+        }
+
+        return intercept;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        boolean handled = mInteractionEventHandler.handleTouchEvent(ev);
+
+        if (!handled) {
+            handled = super.onTouchEvent(ev);
+        }
+
+        if (!handled) {
+            mInteractionEventHandler.didNotHandleTouchEvent(ev);
+        }
+
+        return handled;
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if (DEBUG) {
+            Paint pt = new Paint();
+            pt.setColor(0x80FFFF00);
+            pt.setStrokeWidth(12.0f);
+            pt.setStyle(Paint.Style.STROKE);
+            canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), pt);
+        }
+    }
+
+    class LayoutParams extends FrameLayout.LayoutParams {
+
+        public boolean ignoreRightInset;
+
+        LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+
+            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout);
+            ignoreRightInset = a.getBoolean(
+                    R.styleable.StatusBarWindowView_Layout_ignoreRightInset, false);
+            a.recycle();
+        }
+    }
+
+    @Override
+    public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback,
+            int type) {
+        if (type == ActionMode.TYPE_FLOATING) {
+            return startActionMode(originalView, callback, type);
+        }
+        return super.startActionModeForChild(originalView, callback, type);
+    }
+
+    private ActionMode createFloatingActionMode(
+            View originatingView, ActionMode.Callback2 callback) {
+        if (mFloatingActionMode != null) {
+            mFloatingActionMode.finish();
+        }
+        cleanupFloatingActionModeViews();
+        mFloatingToolbar = new FloatingToolbar(mFakeWindow);
+        final FloatingActionMode mode =
+                new FloatingActionMode(mContext, callback, originatingView, mFloatingToolbar);
+        mFloatingActionModeOriginatingView = originatingView;
+        mFloatingToolbarPreDrawListener =
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        mode.updateViewLocationInWindow();
+                        return true;
+                    }
+                };
+        return mode;
+    }
+
+    private void setHandledFloatingActionMode(ActionMode mode) {
+        mFloatingActionMode = mode;
+        mFloatingActionMode.invalidate();  // Will show the floating toolbar if necessary.
+        mFloatingActionModeOriginatingView.getViewTreeObserver()
+                .addOnPreDrawListener(mFloatingToolbarPreDrawListener);
+    }
+
+    private void cleanupFloatingActionModeViews() {
+        if (mFloatingToolbar != null) {
+            mFloatingToolbar.dismiss();
+            mFloatingToolbar = null;
+        }
+        if (mFloatingActionModeOriginatingView != null) {
+            if (mFloatingToolbarPreDrawListener != null) {
+                mFloatingActionModeOriginatingView.getViewTreeObserver()
+                        .removeOnPreDrawListener(mFloatingToolbarPreDrawListener);
+                mFloatingToolbarPreDrawListener = null;
+            }
+            mFloatingActionModeOriginatingView = null;
+        }
+    }
+
+    private ActionMode startActionMode(
+            View originatingView, ActionMode.Callback callback, int type) {
+        ActionMode.Callback2 wrappedCallback = new ActionModeCallback2Wrapper(callback);
+        ActionMode mode = createFloatingActionMode(originatingView, wrappedCallback);
+        if (mode != null && wrappedCallback.onCreateActionMode(mode, mode.getMenu())) {
+            setHandledFloatingActionMode(mode);
+        } else {
+            mode = null;
+        }
+        return mode;
+    }
+
+    private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
+        private final ActionMode.Callback mWrapped;
+
+        ActionModeCallback2Wrapper(ActionMode.Callback wrapped) {
+            mWrapped = wrapped;
+        }
+
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            return mWrapped.onCreateActionMode(mode, menu);
+        }
+
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            requestFitSystemWindows();
+            return mWrapped.onPrepareActionMode(mode, menu);
+        }
+
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            return mWrapped.onActionItemClicked(mode, item);
+        }
+
+        public void onDestroyActionMode(ActionMode mode) {
+            mWrapped.onDestroyActionMode(mode);
+            if (mode == mFloatingActionMode) {
+                cleanupFloatingActionModeViews();
+                mFloatingActionMode = null;
+            }
+            requestFitSystemWindows();
+        }
+
+        @Override
+        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
+            if (mWrapped instanceof ActionMode.Callback2) {
+                ((ActionMode.Callback2) mWrapped).onGetContentRect(mode, view, outRect);
+            } else {
+                super.onGetContentRect(mode, view, outRect);
+            }
+        }
+    }
+
+    interface InteractionEventHandler {
+        /**
+         * Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer
+         * to the super method.
+         */
+        Boolean handleDispatchTouchEvent(MotionEvent ev);
+
+        /**
+         * Returns if the view should intercept the touch event.
+         *
+         * The touch event may still be interecepted if
+         * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)} decides to do so.
+         */
+        boolean shouldInterceptTouchEvent(MotionEvent ev);
+
+        /**
+         * Called when the view decides to intercept the touch event.
+         */
+        void didIntercept(MotionEvent ev);
+
+        boolean handleTouchEvent(MotionEvent ev);
+
+        void didNotHandleTouchEvent(MotionEvent ev);
+
+        boolean interceptMediaKey(KeyEvent event);
+
+        boolean dispatchKeyEvent(KeyEvent event);
+    }
+
+    /**
+     * Minimal window to satisfy FloatingToolbar.
+     */
+    private Window mFakeWindow = new Window(mContext) {
+        @Override
+        public void takeSurface(SurfaceHolder.Callback2 callback) {
+        }
+
+        @Override
+        public void takeInputQueue(InputQueue.Callback callback) {
+        }
+
+        @Override
+        public boolean isFloating() {
+            return false;
+        }
+
+        @Override
+        public void alwaysReadCloseOnTouchAttr() {
+        }
+
+        @Override
+        public void setContentView(@LayoutRes int layoutResID) {
+        }
+
+        @Override
+        public void setContentView(View view) {
+        }
+
+        @Override
+        public void setContentView(View view, ViewGroup.LayoutParams params) {
+        }
+
+        @Override
+        public void addContentView(View view, ViewGroup.LayoutParams params) {
+        }
+
+        @Override
+        public void clearContentView() {
+        }
+
+        @Override
+        public View getCurrentFocus() {
+            return null;
+        }
+
+        @Override
+        public LayoutInflater getLayoutInflater() {
+            return null;
+        }
+
+        @Override
+        public void setTitle(CharSequence title) {
+        }
+
+        @Override
+        public void setTitleColor(@ColorInt int textColor) {
+        }
+
+        @Override
+        public void openPanel(int featureId, KeyEvent event) {
+        }
+
+        @Override
+        public void closePanel(int featureId) {
+        }
+
+        @Override
+        public void togglePanel(int featureId, KeyEvent event) {
+        }
+
+        @Override
+        public void invalidatePanelMenu(int featureId) {
+        }
+
+        @Override
+        public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) {
+            return false;
+        }
+
+        @Override
+        public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
+            return false;
+        }
+
+        @Override
+        public void closeAllPanels() {
+        }
+
+        @Override
+        public boolean performContextMenuIdentifierAction(int id, int flags) {
+            return false;
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+        }
+
+        @Override
+        public void setBackgroundDrawable(Drawable drawable) {
+        }
+
+        @Override
+        public void setFeatureDrawableResource(int featureId, @DrawableRes int resId) {
+        }
+
+        @Override
+        public void setFeatureDrawableUri(int featureId, Uri uri) {
+        }
+
+        @Override
+        public void setFeatureDrawable(int featureId, Drawable drawable) {
+        }
+
+        @Override
+        public void setFeatureDrawableAlpha(int featureId, int alpha) {
+        }
+
+        @Override
+        public void setFeatureInt(int featureId, int value) {
+        }
+
+        @Override
+        public void takeKeyEvents(boolean get) {
+        }
+
+        @Override
+        public boolean superDispatchKeyEvent(KeyEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchTouchEvent(MotionEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchTrackballEvent(MotionEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchGenericMotionEvent(MotionEvent event) {
+            return false;
+        }
+
+        @Override
+        public View getDecorView() {
+            return NotificationShadeWindowView.this;
+        }
+
+        @Override
+        public View peekDecorView() {
+            return null;
+        }
+
+        @Override
+        public Bundle saveHierarchyState() {
+            return null;
+        }
+
+        @Override
+        public void restoreHierarchyState(Bundle savedInstanceState) {
+        }
+
+        @Override
+        protected void onActive() {
+        }
+
+        @Override
+        public void setChildDrawable(int featureId, Drawable drawable) {
+        }
+
+        @Override
+        public void setChildInt(int featureId, int value) {
+        }
+
+        @Override
+        public boolean isShortcutKey(int keyCode, KeyEvent event) {
+            return false;
+        }
+
+        @Override
+        public void setVolumeControlStream(int streamType) {
+        }
+
+        @Override
+        public int getVolumeControlStream() {
+            return 0;
+        }
+
+        @Override
+        public int getStatusBarColor() {
+            return 0;
+        }
+
+        @Override
+        public void setStatusBarColor(@ColorInt int color) {
+        }
+
+        @Override
+        public int getNavigationBarColor() {
+            return 0;
+        }
+
+        @Override
+        public void setNavigationBarColor(@ColorInt int color) {
+        }
+
+        @Override
+        public void setDecorCaptionShade(int decorCaptionShade) {
+        }
+
+        @Override
+        public void setResizingCaptionDrawable(Drawable drawable) {
+        }
+
+        @Override
+        public void onMultiWindowModeChanged() {
+        }
+
+        @Override
+        public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
+        }
+
+        @Override
+        public void reportActivityRelaunched() {
+        }
+
+        @Override
+        public WindowInsetsController getInsetsController() {
+            return null;
+        }
+    };
+
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 4935f0e..c691a35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -16,7 +16,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
+
 import android.app.StatusBarManager;
+import android.graphics.RectF;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.media.AudioManager;
 import android.media.session.MediaSessionLegacyHelper;
@@ -56,9 +59,9 @@
 import javax.inject.Inject;
 
 /**
- * Controller for {@link StatusBarWindowView}.
+ * Controller for {@link NotificationShadeWindowView}.
  */
-public class StatusBarWindowViewController {
+public class NotificationShadeWindowViewController {
     private final InjectionInflationController mInjectionInflationController;
     private final NotificationWakeUpCoordinator mCoordinator;
     private final PulseExpansionHandler mPulseExpansionHandler;
@@ -74,7 +77,7 @@
     private final DozeLog mDozeLog;
     private final DozeParameters mDozeParameters;
     private final CommandQueue mCommandQueue;
-    private final StatusBarWindowView mView;
+    private final NotificationShadeWindowView mView;
     private final ShadeController mShadeController;
 
     private GestureDetector mGestureDetector;
@@ -93,8 +96,13 @@
     private final DockManager mDockManager;
     private final NotificationPanelViewController mNotificationPanelViewController;
 
+    // Used for determining view / touch intersection
+    private int[] mTempLocation = new int[2];
+    private RectF mTempRect = new RectF();
+    private boolean mIsTrackingBarGesture = false;
+
     @Inject
-    public StatusBarWindowViewController(
+    public NotificationShadeWindowViewController(
             InjectionInflationController injectionInflationController,
             NotificationWakeUpCoordinator coordinator,
             PulseExpansionHandler pulseExpansionHandler,
@@ -112,7 +120,7 @@
             CommandQueue commandQueue,
             ShadeController shadeController,
             DockManager dockManager,
-            StatusBarWindowView statusBarWindowView,
+            NotificationShadeWindowView statusBarWindowView,
             NotificationPanelViewController notificationPanelViewController) {
         mInjectionInflationController = injectionInflationController;
         mCoordinator = coordinator;
@@ -182,7 +190,7 @@
                 };
         mGestureDetector = new GestureDetector(mView.getContext(), gestureListener);
 
-        mView.setInteractionEventHandler(new StatusBarWindowView.InteractionEventHandler() {
+        mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
             @Override
             public Boolean handleDispatchTouchEvent(MotionEvent ev) {
                 boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
@@ -244,6 +252,26 @@
                     return mStatusBarView.dispatchTouchEvent(ev);
                 }
 
+                if (!mIsTrackingBarGesture && isDown
+                        && mNotificationPanelViewController.isFullyCollapsed()) {
+                    float x = ev.getRawX();
+                    float y = ev.getRawY();
+                    if (isIntersecting(mStatusBarView, x, y)) {
+                        if (mService.isSameStatusBarState(WINDOW_STATE_SHOWING)) {
+                            mIsTrackingBarGesture = true;
+                            return mStatusBarView.dispatchTouchEvent(ev);
+                        } else { // it's hidden or hiding, don't send to notification shade.
+                            return true;
+                        }
+                    }
+                } else if (mIsTrackingBarGesture) {
+                    final boolean sendToNotification = mStatusBarView.dispatchTouchEvent(ev);
+                    if (isUp || isCancel) {
+                        mIsTrackingBarGesture = false;
+                    }
+                    return sendToNotification;
+                }
+
                 return null;
             }
 
@@ -357,7 +385,7 @@
                         dragDownCallback, mFalsingManager));
     }
 
-    public StatusBarWindowView getView() {
+    public NotificationShadeWindowView getView() {
         return mView;
     }
 
@@ -414,4 +442,11 @@
     void setDragDownHelper(DragDownHelper dragDownHelper) {
         mDragDownHelper = dragDownHelper;
     }
+
+    private boolean isIntersecting(View view, float x, float y) {
+        mTempLocation = view.getLocationOnScreen();
+        mTempRect.set(mTempLocation[0], mTempLocation[1], mTempLocation[0] + view.getWidth(),
+                mTempLocation[1] + view.getHeight());
+        return mTempRect.contains(x, y);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 3d8e09a..af46f7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -783,8 +783,7 @@
                             mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                             return;
                         }
-                        if (mStatusBar.getStatusBarWindow().getHeight()
-                                != mStatusBar.getStatusBarHeight()) {
+                        if (mStatusBar.getNotificationShadeWindowView().isVisibleToUser()) {
                             mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                             if (mAnimateAfterExpanding) {
                                 notifyExpandingStarted();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 45f3bf9..ffbbffc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -323,8 +323,7 @@
                 R.dimen.display_cutout_margin_consumption);
 
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
-        layoutParams.height = getResources().getDimensionPixelSize(
-                R.dimen.status_bar_height);
+        layoutParams.height = getResources().getDimensionPixelSize(R.dimen.status_bar_height);
         setLayoutParams(layoutParams);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
index 866dc2d..3330615 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
@@ -44,7 +44,7 @@
 
     private final CommandQueue mCommandQueue;
     private final StatusBarStateController mStatusBarStateController;
-    protected final StatusBarWindowController mStatusBarWindowController;
+    protected final NotificationShadeWindowController mNotificationShadeWindowController;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final int mDisplayId;
     protected final Lazy<StatusBar> mStatusBarLazy;
@@ -57,7 +57,7 @@
     public ShadeControllerImpl(
             CommandQueue commandQueue,
             StatusBarStateController statusBarStateController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             WindowManager windowManager,
             Lazy<StatusBar> statusBarLazy,
@@ -66,7 +66,7 @@
     ) {
         mCommandQueue = commandQueue;
         mStatusBarStateController = statusBarStateController;
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mDisplayId = windowManager.getDefaultDisplay().getDisplayId();
         // TODO: Remove circular reference to StatusBar when possible.
@@ -122,14 +122,15 @@
         }
 
         // TODO(b/62444020): remove when this bug is fixed
-        Log.v(TAG, "mStatusBarWindow: " + getStatusBarWindowView() + " canPanelBeCollapsed(): "
+        Log.v(TAG, "NotificationShadeWindow: " + getNotificationShadeWindowView()
+                + " canPanelBeCollapsed(): "
                 + getNotificationPanelViewController().canPanelBeCollapsed());
-        if (getStatusBarWindowView() != null
+        if (getNotificationShadeWindowView() != null
                 && getNotificationPanelViewController().canPanelBeCollapsed()) {
             // release focus immediately to kick off focus change transition
-            mStatusBarWindowController.setStatusBarFocusable(false);
+            mNotificationShadeWindowController.setNotificationShadeFocusable(false);
 
-            getStatusBar().getStatusBarWindowViewController().cancelExpandHelper();
+            getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();
             getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor);
         } else {
             mBubbleControllerLazy.get().collapseStack();
@@ -154,8 +155,7 @@
                 new ViewTreeObserver.OnGlobalLayoutListener() {
                     @Override
                     public void onGlobalLayout() {
-                        if (getStatusBar().getStatusBarWindow().getHeight()
-                                != getStatusBar().getStatusBarHeight()) {
+                        if (getStatusBar().getNotificationShadeWindowView().isVisibleToUser()) {
                             getNotificationPanelViewController().removeOnGlobalLayoutListener(this);
                             getNotificationPanelViewController().getView().post(executable);
                         }
@@ -222,8 +222,8 @@
         return getStatusBar().getPresenter();
     }
 
-    protected StatusBarWindowView getStatusBarWindowView() {
-        return getStatusBar().getStatusBarWindow();
+    protected NotificationShadeWindowView getNotificationShadeWindowView() {
+        return getStatusBar().getNotificationShadeWindowView();
     }
 
     protected PhoneStatusBarView getStatusBarView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index dc9cf77..4e8442f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -342,9 +342,11 @@
 
     private final Point mCurrentDisplaySize = new Point();
 
-    protected StatusBarWindowView mStatusBarWindow;
+    protected NotificationShadeWindowView mNotificationShadeWindowView;
+    protected StatusBarWindowView mPhoneStatusBarWindow;
     protected PhoneStatusBarView mStatusBarView;
     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
+    protected NotificationShadeWindowController mNotificationShadeWindowController;
     protected StatusBarWindowController mStatusBarWindowController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final LockscreenLockIconController mLockscreenLockIconController;
@@ -368,7 +370,7 @@
     private final FalsingManager mFalsingManager;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final ConfigurationController mConfigurationController;
-    protected StatusBarWindowViewController mStatusBarWindowViewController;
+    protected NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     private final DozeParameters mDozeParameters;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
     private final Provider<StatusBarComponent.Builder> mStatusBarComponentBuilder;
@@ -503,7 +505,7 @@
                     && ((info == null && imageWallpaperInAmbient)
                         || (info != null && info.supportsAmbientMode()));
 
-            mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
+            mNotificationShadeWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
             mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
         }
     };
@@ -659,7 +661,7 @@
             Lazy<AssistManager> assistManagerLazy,
             NotificationListener notificationListener,
             ConfigurationController configurationController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
@@ -740,7 +742,7 @@
         mAssistManagerLazy = assistManagerLazy;
         mNotificationListener = notificationListener;
         mConfigurationController = configurationController;
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mLockscreenLockIconController = lockscreenLockIconController;
         mDozeServiceHost = dozeServiceHost;
         mPowerManager = powerManager;
@@ -912,7 +914,7 @@
 
         mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
         mDozeServiceHost.initialize(this, mNotificationIconAreaController,
-                mStatusBarKeyguardViewManager, mStatusBarWindowViewController,
+                mStatusBarKeyguardViewManager, mNotificationShadeWindowViewController,
                 mNotificationPanelViewController, mAmbientIndicationContainer);
 
         mConfigurationController.addCallback(this);
@@ -930,7 +932,8 @@
                     @Override
                     public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
                         mMainThreadHandler.post(
-                                () -> plugin.setup(getStatusBarWindow(), getNavigationBarView(),
+                                () -> plugin.setup(getNotificationShadeWindowView(),
+                                        getNavigationBarView(),
                                         new Callback(plugin), mDozeParameters));
                     }
 
@@ -938,7 +941,8 @@
                     public void onPluginDisconnected(OverlayPlugin plugin) {
                         mMainThreadHandler.post(() -> {
                             mOverlays.remove(plugin);
-                            mStatusBarWindowController.setForcePluginOpen(mOverlays.size() != 0);
+                            mNotificationShadeWindowController
+                                    .setForcePluginOpen(mOverlays.size() != 0);
                         });
                     }
 
@@ -957,10 +961,10 @@
                                 mOverlays.remove(mPlugin);
                             }
                             mMainThreadHandler.post(() -> {
-                                mStatusBarWindowController
+                                mNotificationShadeWindowController
                                         .setStateListener(b -> mOverlays.forEach(
                                                 o -> o.setCollapseDesired(b)));
-                                mStatusBarWindowController
+                                mNotificationShadeWindowController
                                         .setForcePluginOpen(mOverlays.size() != 0);
                             });
                         }
@@ -978,12 +982,13 @@
         updateTheme();
 
         inflateStatusBarWindow();
-        mStatusBarWindowViewController.setService(this);
-        mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
+        mNotificationShadeWindowViewController.setService(this);
+        mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
 
         // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
-        mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
+        mStackScroller = mNotificationShadeWindowView.findViewById(
+                R.id.notification_stack_scroller);
         NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
         mNotificationLogger.setUpWithContainer(notifListContainer);
 
@@ -1004,17 +1009,18 @@
         // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
         mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
         mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
-        FragmentHostManager.get(mStatusBarWindow)
+        FragmentHostManager.get(mPhoneStatusBarWindow)
                 .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
                     CollapsedStatusBarFragment statusBarFragment =
                             (CollapsedStatusBarFragment) fragment;
-                    statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
+
                     PhoneStatusBarView oldStatusBarView = mStatusBarView;
-                    mStatusBarView = (PhoneStatusBarView) fragment.getView();
+                    mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
                     mStatusBarView.setBar(this);
                     mStatusBarView.setPanel(mNotificationPanelViewController);
                     mStatusBarView.setScrimController(mScrimController);
 
+                    statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
                     // CollapsedStatusBarFragment re-inflated PhoneStatusBarView and both of
                     // mStatusBarView.mExpanded and mStatusBarView.mBouncerShowing are false.
                     // PhoneStatusBarView's new instance will set to be gone in
@@ -1038,16 +1044,18 @@
                         mHeadsUpAppearanceController.destroy();
                     }
                     // TODO: this should probably be scoped to the StatusBarComponent
+                    // TODO (b/136993073) Separate notification shade and status bar
                     mHeadsUpAppearanceController = new HeadsUpAppearanceController(
-                            mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow,
+                            mNotificationIconAreaController, mHeadsUpManager,
+                            mNotificationShadeWindowView,
                             mStatusBarStateController, mKeyguardBypassController,
                             mKeyguardStateController, mWakeUpCoordinator, mCommandQueue,
-                            mNotificationPanelViewController);
+                            mNotificationPanelViewController, mStatusBarView);
                     mHeadsUpAppearanceController.readFrom(oldController);
 
                     mLightsOutNotifController.setLightsOutNotifView(
                             mStatusBarView.findViewById(R.id.notification_lights_out));
-                    mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
+                    mNotificationShadeWindowViewController.setStatusBarView(mStatusBarView);
                     checkBarModes();
                 }).getFragmentManager()
                 .beginTransaction()
@@ -1055,7 +1063,8 @@
                         CollapsedStatusBarFragment.TAG)
                 .commit();
 
-        mHeadsUpManager.setUp(mStatusBarWindow, mGroupManager, this, mVisualStabilityManager);
+        mHeadsUpManager.setUp(mNotificationShadeWindowView, mGroupManager, this,
+                mVisualStabilityManager);
         mConfigurationController.addCallback(mHeadsUpManager);
         mHeadsUpManager.addListener(this);
         mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
@@ -1075,12 +1084,12 @@
 
         mKeyguardIndicationController =
                 SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
-                        mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
-                        mStatusBarWindow.findViewById(R.id.lock_icon));
+                        mNotificationShadeWindowView.findViewById(R.id.keyguard_indication_area),
+                        mNotificationShadeWindowView.findViewById(R.id.lock_icon));
         mNotificationPanelViewController.setKeyguardIndicationController(
                 mKeyguardIndicationController);
 
-        mAmbientIndicationContainer = mStatusBarWindow.findViewById(
+        mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
                 R.id.ambient_indication_container);
 
         // TODO: Find better place for this callback.
@@ -1101,13 +1110,13 @@
 
         mAutoHideController.setStatusBar(this);
 
-        ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind);
-        ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front);
-        ScrimView scrimForBubble = mStatusBarWindow.findViewById(R.id.scrim_for_bubble);
+        ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
+        ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
+        ScrimView scrimForBubble = mNotificationShadeWindowView.findViewById(R.id.scrim_for_bubble);
 
         mScrimController.setScrimVisibleListener(scrimsVisible -> {
-            mStatusBarWindowController.setScrimsVisibility(scrimsVisible);
-            if (mStatusBarWindow != null) {
+            mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
+            if (mNotificationShadeWindowView != null) {
                 mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
             }
         });
@@ -1116,7 +1125,7 @@
         mNotificationPanelViewController.initDependencies(this, mGroupManager, mNotificationShelf,
                 mNotificationIconAreaController, mScrimController);
 
-        BackDropView backdrop = mStatusBarWindow.findViewById(R.id.backdrop);
+        BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
         mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
                 backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
 
@@ -1129,7 +1138,7 @@
                 mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
 
         // Set up the quick settings tile panel
-        View container = mStatusBarWindow.findViewById(R.id.qs_frame);
+        final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
         if (container != null) {
             FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
             ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
@@ -1138,7 +1147,8 @@
                             .withPlugin(QS.class)
                             .withDefault(this::createDefaultQSFragment)
                             .build());
-            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow,
+            mBrightnessMirrorController = new BrightnessMirrorController(
+                    mNotificationShadeWindowView,
                     mNotificationPanelViewController,
                     (visible) -> {
                         mBrightnessMirrorVisible = visible;
@@ -1153,7 +1163,8 @@
             });
         }
 
-        mReportRejectedTouch = mStatusBarWindow.findViewById(R.id.report_rejected_touch);
+        mReportRejectedTouch = mNotificationShadeWindowView
+                .findViewById(R.id.report_rejected_touch);
         if (mReportRejectedTouch != null) {
             updateReportRejectedTouchVisibility();
             mReportRejectedTouch.setOnClickListener(v -> {
@@ -1227,18 +1238,18 @@
     }
 
     protected QS createDefaultQSFragment() {
-        return FragmentHostManager.get(mStatusBarWindow).create(QSFragment.class);
+        return FragmentHostManager.get(mNotificationShadeWindowView).create(QSFragment.class);
     }
 
     private void setUpPresenter() {
         // Set up the initial notification state.
         mActivityLaunchAnimator = new ActivityLaunchAnimator(
-                mStatusBarWindowViewController, this, mNotificationPanelViewController,
+                mNotificationShadeWindowViewController, this, mNotificationPanelViewController,
                 (NotificationListContainer) mStackScroller);
 
         // TODO: inject this.
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanelViewController,
-                mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
+                mHeadsUpManager, mNotificationShadeWindowView, mStackScroller, mDozeScrimController,
                 mScrimController, mActivityLaunchAnimator, mDynamicPrivacyController,
                 mNotificationAlertingManager, mNotificationRowBinder, mKeyguardStateController,
                 mKeyguardIndicationController,
@@ -1251,7 +1262,7 @@
                         mDeviceProvisionedController);
 
         mNotificationShelf.setOnActivatedListener(mPresenter);
-        mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
+        mRemoteInputManager.getController().addCallback(mNotificationShadeWindowController);
 
         mNotificationActivityStarter =
                 mStatusBarNotificationActivityStarterBuilder
@@ -1328,7 +1339,7 @@
                     mShadeController.animateCollapsePanels();
                 }
             }
-            return mStatusBarWindow.onTouchEvent(event);
+            return mNotificationShadeWindowView.onTouchEvent(event);
         };
     }
 
@@ -1384,17 +1395,20 @@
 
     protected void createUserSwitcher() {
         mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
-                mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
-                mStatusBarWindow.findViewById(R.id.keyguard_header),
+                mNotificationShadeWindowView.findViewById(R.id.keyguard_user_switcher),
+                mNotificationShadeWindowView.findViewById(R.id.keyguard_header),
                 mNotificationPanelViewController);
     }
 
     private void inflateStatusBarWindow() {
-        mStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
+        mNotificationShadeWindowView = mSuperStatusBarViewFactory.getNotificationShadeWindowView();
         StatusBarComponent statusBarComponent = mStatusBarComponentBuilder.get()
-                .statusBarWindowView(mStatusBarWindow).build();
-        mStatusBarWindowViewController = statusBarComponent.getStatusBarWindowViewController();
-        mStatusBarWindowViewController.setupExpandedStatusBar();
+                .statusBarWindowView(mNotificationShadeWindowView).build();
+        mNotificationShadeWindowViewController = statusBarComponent
+                .getNotificationShadeWindowViewController();
+        mNotificationShadeWindowViewController.setupExpandedStatusBar();
+        mStatusBarWindowController = statusBarComponent.getStatusBarWindowController();
+        mPhoneStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
         mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
     }
 
@@ -1404,7 +1418,8 @@
         mStatusBarKeyguardViewManager.registerStatusBar(
                 /* statusBar= */ this, getBouncerContainer(),
                 mNotificationPanelViewController, mBiometricUnlockController,
-                mDismissCallbackRegistry, mStatusBarWindow.findViewById(R.id.lock_icon_container),
+                mDismissCallbackRegistry,
+                mNotificationShadeWindowView.findViewById(R.id.lock_icon_container),
                 mStackScroller, mKeyguardBypassController, mFalsingManager);
         mKeyguardIndicationController
                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -1422,16 +1437,20 @@
         return mStatusBarView;
     }
 
-    public StatusBarWindowView getStatusBarWindow() {
-        return mStatusBarWindow;
+    public NotificationShadeWindowView getNotificationShadeWindowView() {
+        return mNotificationShadeWindowView;
     }
 
-    public StatusBarWindowViewController getStatusBarWindowViewController() {
-        return mStatusBarWindowViewController;
+    public StatusBarWindowView getStatusBarWindow() {
+        return mPhoneStatusBarWindow;
+    }
+
+    public NotificationShadeWindowViewController getNotificationShadeWindowViewController() {
+        return mNotificationShadeWindowViewController;
     }
 
     protected ViewGroup getBouncerContainer() {
-        return mStatusBarWindow;
+        return mNotificationShadeWindowView;
     }
 
     public int getStatusBarHeight() {
@@ -1641,7 +1660,7 @@
     }
 
     public void setQsExpanded(boolean expanded) {
-        mStatusBarWindowController.setQsExpanded(expanded);
+        mNotificationShadeWindowController.setQsExpanded(expanded);
         mNotificationPanelViewController.setStatusAccessibilityImportance(expanded
                 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
@@ -1674,7 +1693,7 @@
     @Override
     public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
         if (inPinnedMode) {
-            mStatusBarWindowController.setHeadsUpShowing(true);
+            mNotificationShadeWindowController.setHeadsUpShowing(true);
             mStatusBarWindowController.setForceStatusBarVisible(true);
             if (mNotificationPanelViewController.isFullyCollapsed()) {
                 // We need to ensure that the touchable region is updated before the window will be
@@ -1682,9 +1701,9 @@
                 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
                 // make sure that the window stays small for one frame until the touchableRegion is set.
                 mNotificationPanelViewController.getView().requestLayout();
-                mStatusBarWindowController.setForceWindowCollapsed(true);
+                mNotificationShadeWindowController.setForceWindowCollapsed(true);
                 mNotificationPanelViewController.getView().post(() -> {
-                    mStatusBarWindowController.setForceWindowCollapsed(false);
+                    mNotificationShadeWindowController.setForceWindowCollapsed(false);
                 });
             }
         } else {
@@ -1694,7 +1713,7 @@
                     || mNotificationPanelViewController.isTracking() || bypassKeyguard) {
                 // We are currently tracking or is open and the shade doesn't need to be kept
                 // open artificially.
-                mStatusBarWindowController.setHeadsUpShowing(false);
+                mNotificationShadeWindowController.setHeadsUpShowing(false);
                 if (bypassKeyguard) {
                     mStatusBarWindowController.setForceStatusBarVisible(false);
                 }
@@ -1704,7 +1723,7 @@
                 mHeadsUpManager.setHeadsUpGoingAway(true);
                 mNotificationPanelViewController.runAfterAnimationFinished(() -> {
                     if (!mHeadsUpManager.hasPinnedHeadsUp()) {
-                        mStatusBarWindowController.setHeadsUpShowing(false);
+                        mNotificationShadeWindowController.setHeadsUpShowing(false);
                         mHeadsUpManager.setHeadsUpGoingAway(false);
                     }
                     mRemoteInputManager.onPanelCollapsed();
@@ -1732,7 +1751,7 @@
     public void setPanelExpanded(boolean isExpanded) {
         mPanelExpanded = isExpanded;
         updateHideIconsForBouncer(false /* animate */);
-        mStatusBarWindowController.setPanelExpanded(isExpanded);
+        mNotificationShadeWindowController.setPanelExpanded(isExpanded);
         mVisualStabilityManager.setPanelExpanded(isExpanded);
         if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
             if (DEBUG) {
@@ -1991,7 +2010,7 @@
 
         // Expand the window to encompass the full screen in anticipation of the drag.
         // This is only possible to do atomically because the status bar is at the top of the screen!
-        mStatusBarWindowController.setPanelVisible(true);
+        mNotificationShadeWindowController.setPanelVisible(true);
 
         visibilityChanged(true);
         mCommandQueue.recomputeDisableFlags(mDisplayId, !force /* animate */);
@@ -2100,7 +2119,7 @@
         if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
                 + " mExpandedVisible=" + mExpandedVisible);
 
-        if (!mExpandedVisible || mStatusBarWindow == null) {
+        if (!mExpandedVisible || mNotificationShadeWindowView == null) {
             return;
         }
 
@@ -2113,8 +2132,8 @@
         mExpandedVisible = false;
         visibilityChanged(false);
 
-        // Shrink the window to the size of the status bar only
-        mStatusBarWindowController.setPanelVisible(false);
+        // Update the visibility of notification shade and status bar window.
+        mNotificationShadeWindowController.setPanelVisible(false);
         mStatusBarWindowController.setForceStatusBarVisible(false);
 
         // Close any guts that might be visible
@@ -2178,6 +2197,10 @@
         return false;
     }
 
+    boolean isSameStatusBarState(int state) {
+        return mStatusBarWindowState == state;
+    }
+
     public GestureRecorder getGestureRecorder() {
         return mGestureRec;
     }
@@ -2193,7 +2216,7 @@
             return;
         }
         boolean showing = state == WINDOW_STATE_SHOWING;
-        if (mStatusBarWindow != null
+        if (mNotificationShadeWindowView != null
                 && window == StatusBarManager.WINDOW_STATUS_BAR
                 && mStatusBarWindowState != state) {
             mStatusBarWindowState = state;
@@ -2427,8 +2450,8 @@
             dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
         }
         pw.println("  StatusBarWindowView: ");
-        if (mStatusBarWindowViewController != null) {
-            mStatusBarWindowViewController.dump(fd, pw, args);
+        if (mNotificationShadeWindowViewController != null) {
+            mNotificationShadeWindowViewController.dump(fd, pw, args);
         }
 
         pw.println("  mMediaManager: ");
@@ -2527,6 +2550,7 @@
 
     public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
         makeStatusBarView(result);
+        mNotificationShadeWindowController.attach();
         mStatusBarWindowController.attach();
     }
 
@@ -2690,8 +2714,8 @@
                 }
             }
             else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                if (mStatusBarWindowController != null) {
-                    mStatusBarWindowController.setNotTouchable(false);
+                if (mNotificationShadeWindowController != null) {
+                    mNotificationShadeWindowController.setNotTouchable(false);
                 }
                 if (mBubbleController.isStackExpanded()) {
                     mBubbleController.collapseStack();
@@ -2808,7 +2832,9 @@
             mQSPanel.updateResources();
         }
 
-        mStatusBarWindowController.refreshStatusBarHeight();
+        if (mStatusBarWindowController != null) {
+            mStatusBarWindowController.refreshStatusBarHeight();
+        }
 
         if (mStatusBarView != null) {
             mStatusBarView.updateResources();
@@ -3518,7 +3544,7 @@
         if (!mPresenter.isPresenterFullyCollapsed()) {
             // if we set it not to be focusable when collapsing, we have to undo it when we aborted
             // the closing
-            mStatusBarWindowController.setStatusBarFocusable(true);
+            mNotificationShadeWindowController.setNotificationShadeFocusable(true);
         }
     }
 
@@ -3631,7 +3657,7 @@
      */
     public void collapseShade() {
         if (mNotificationPanelViewController.isTracking()) {
-            mStatusBarWindowViewController.cancelCurrentTouch();
+            mNotificationShadeWindowViewController.cancelCurrentTouch();
         }
         if (mPanelExpanded && mState == StatusBarState.SHADE) {
             mShadeController.animateCollapsePanels();
@@ -3652,7 +3678,7 @@
             updateVisibleToUser();
 
             updateNotificationPanelTouchState();
-            mStatusBarWindowViewController.cancelCurrentTouch();
+            mNotificationShadeWindowViewController.cancelCurrentTouch();
             if (mLaunchCameraOnFinishedGoingToSleep) {
                 mLaunchCameraOnFinishedGoingToSleep = false;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 5daef24..75da5d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -76,12 +76,12 @@
 
     public static final String ICON_BLACKLIST = "icon_blacklist";
 
-    public static ArraySet<String> getIconBlacklist(String blackListStr) {
+    /** Reads the default blacklist from config value unless blacklistStr is provided. */
+    static ArraySet<String> getIconBlacklist(Context context, String blackListStr) {
         ArraySet<String> ret = new ArraySet<>();
-        if (blackListStr == null) {
-            blackListStr = "rotate,headset";
-        }
-        String[] blacklist = blackListStr.split(",");
+        String[] blacklist = blackListStr == null
+            ? context.getResources().getStringArray(R.array.config_statusBarIconBlackList)
+            : blackListStr.split(",");
         for (String slot : blacklist) {
             if (!TextUtils.isEmpty(slot)) {
                 ret.add(slot);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index aa062eb..bfcbcea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -111,7 +111,7 @@
             return;
         }
         mIconBlacklist.clear();
-        mIconBlacklist.addAll(StatusBarIconController.getIconBlacklist(newValue));
+        mIconBlacklist.addAll(StatusBarIconController.getIconBlacklist(mContext, newValue));
         ArrayList<Slot> currentSlots = getSlots();
         ArrayMap<Slot, List<StatusBarIconHolder>> slotsToReAdd = new ArrayMap<>();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index eb911bc..86a81ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -92,7 +92,7 @@
     private static String TAG = "StatusBarKeyguardViewManager";
 
     protected final Context mContext;
-    private final StatusBarWindowController mStatusBarWindowController;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() {
         @Override
         public void onFullyShown() {
@@ -199,13 +199,13 @@
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             NavigationModeController navigationModeController,
             DockManager dockManager,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             KeyguardStateController keyguardStateController,
             NotificationMediaManager notificationMediaManager) {
         mContext = context;
         mViewMediatorCallback = callback;
         mLockPatternUtils = lockPatternUtils;
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mKeyguardStateController = keyguardStateController;
         mMediaManager = notificationMediaManager;
         mKeyguardUpdateManager = keyguardUpdateMonitor;
@@ -315,7 +315,7 @@
      */
     public void show(Bundle options) {
         mShowing = true;
-        mStatusBarWindowController.setKeyguardShowing(true);
+        mNotificationShadeWindowController.setKeyguardShowing(true);
         mKeyguardStateController.notifyKeyguardState(mShowing,
                 mKeyguardStateController.isOccluded());
         reset(true /* hideBouncerWhenShowing */);
@@ -491,11 +491,11 @@
     }
 
     public void setNeedsInput(boolean needsInput) {
-        mStatusBarWindowController.setKeyguardNeedsInput(needsInput);
+        mNotificationShadeWindowController.setKeyguardNeedsInput(needsInput);
     }
 
     public boolean isUnlockWithWallpaper() {
-        return mStatusBarWindowController.isShowingWallpaper();
+        return mNotificationShadeWindowController.isShowingWallpaper();
     }
 
     public void setOccluded(boolean occluded, boolean animate) {
@@ -509,7 +509,7 @@
                         new Runnable() {
                             @Override
                             public void run() {
-                                mStatusBarWindowController.setKeyguardOccluded(mOccluded);
+                                mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
                                 reset(true /* hideBouncerWhenShowing */);
                             }
                         });
@@ -524,7 +524,7 @@
         if (mShowing) {
             mMediaManager.updateMediaMetaData(false, animate && !occluded);
         }
-        mStatusBarWindowController.setKeyguardOccluded(occluded);
+        mNotificationShadeWindowController.setKeyguardOccluded(occluded);
 
         // setDozing(false) will call reset once we stop dozing.
         if (!mDozing) {
@@ -578,8 +578,8 @@
             mStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
                 @Override
                 public void run() {
-                    mStatusBarWindowController.setKeyguardShowing(false);
-                    mStatusBarWindowController.setKeyguardFadingAway(true);
+                    mNotificationShadeWindowController.setKeyguardShowing(false);
+                    mNotificationShadeWindowController.setKeyguardFadingAway(true);
                     hideBouncer(true /* destroyView */);
                     updateStates();
                 }
@@ -587,7 +587,7 @@
                 @Override
                 public void run() {
                     mStatusBar.hideKeyguard();
-                    mStatusBarWindowController.setKeyguardFadingAway(false);
+                    mNotificationShadeWindowController.setKeyguardFadingAway(false);
                     mViewMediatorCallback.keyguardGone();
                     executeAfterKeyguardGoneAction();
                 }
@@ -624,7 +624,7 @@
             } else {
                 boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
                 if (!staying) {
-                    mStatusBarWindowController.setKeyguardFadingAway(true);
+                    mNotificationShadeWindowController.setKeyguardFadingAway(true);
                     if (needsFading) {
                         ViewGroupFadeHelper.fadeOutAllChildrenExcept(
                                 mNotificationPanelViewController.getView(),
@@ -650,7 +650,7 @@
             }
             updateLockIcon();
             updateStates();
-            mStatusBarWindowController.setKeyguardShowing(false);
+            mNotificationShadeWindowController.setKeyguardShowing(false);
             mViewMediatorCallback.keyguardGone();
         }
         SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
@@ -684,8 +684,8 @@
     }
 
     public void onKeyguardFadedAway() {
-        mContainer.postDelayed(() -> mStatusBarWindowController.setKeyguardFadingAway(false),
-                100);
+        mContainer.postDelayed(() -> mNotificationShadeWindowController
+                        .setKeyguardFadingAway(false), 100);
         ViewGroupFadeHelper.reset(mNotificationPanelViewController.getView());
         mStatusBar.finishKeyguardFadingAway();
         mBiometricUnlockController.finishKeyguardFadingAway();
@@ -818,7 +818,7 @@
         }
 
         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
-            mStatusBarWindowController.setBouncerShowing(bouncerShowing);
+            mNotificationShadeWindowController.setBouncerShowing(bouncerShowing);
             mStatusBar.setBouncerShowing(bouncerShowing);
             updateLockIcon();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
index b4d5dad..7615bf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
@@ -151,7 +151,7 @@
             Lazy<AssistManager> assistManagerLazy,
             NotificationListener notificationListener,
             ConfigurationController configurationController,
-            StatusBarWindowController statusBarWindowController,
+            NotificationShadeWindowController notificationShadeWindowController,
             LockscreenLockIconController lockscreenLockIconController,
             DozeParameters dozeParameters,
             ScrimController scrimController,
@@ -233,7 +233,7 @@
                 assistManagerLazy,
                 notificationListener,
                 configurationController,
-                statusBarWindowController,
+                notificationShadeWindowController,
                 lockscreenLockIconController,
                 dozeParameters,
                 scrimController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 720f229..1336b2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -134,7 +134,7 @@
     public StatusBarNotificationPresenter(Context context,
             NotificationPanelViewController panel,
             HeadsUpManagerPhone headsUp,
-            StatusBarWindowView statusBarWindow,
+            NotificationShadeWindowView statusBarWindow,
             ViewGroup stackScroller,
             DozeScrimController dozeScrimController,
             ScrimController scrimController,
@@ -191,7 +191,7 @@
                 Dependency.get(NotificationRemoteInputManager.Callback.class),
                 mNotificationPanel.createRemoteInputDelegate());
         remoteInputManager.getController().addCallback(
-                Dependency.get(StatusBarWindowController.class));
+                Dependency.get(NotificationShadeWindowController.class));
 
         NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller;
         initController.addPostInitTask(() -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 8286d26..d2e9262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -117,7 +117,7 @@
         if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
             return;
         }
-        ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(newValue);
+        ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(mContext, newValue);
         boolean blockAirplane = blockList.contains(mSlotAirplane);
         boolean blockMobile = blockList.contains(mSlotMobile);
         boolean blockWifi = blockList.contains(mSlotWifi);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 3d25749..b8fb6d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -17,15 +17,13 @@
 package com.android.systemui.statusbar.phone;
 
 import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Rect;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -38,60 +36,62 @@
         OnComputeInternalInsetsListener, ConfigurationListener {
 
     private final BubbleController mBubbleController = Dependency.get(BubbleController.class);
-    private final Context mContext;
     private final HeadsUpManagerPhone mHeadsUpManager;
     private boolean mIsStatusBarExpanded = false;
     private boolean mShouldAdjustInsets = false;
     private final StatusBar mStatusBar;
-    private int mStatusBarHeight;
-    private final View mStatusBarWindowView;
+    private final View mNotificationShadeWindowView;
+    private View mNotificationPanelView;
     private boolean mForceCollapsedUntilLayout = false;
-    private final StatusBarWindowController mStatusBarWindowController;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
 
-    public StatusBarTouchableRegionManager(@NonNull Context context,
-                                           HeadsUpManagerPhone headsUpManager,
+    public StatusBarTouchableRegionManager(HeadsUpManagerPhone headsUpManager,
                                            @NonNull StatusBar statusBar,
-                                           @NonNull View statusBarWindowView) {
-        mContext = context;
+                                           @NonNull View notificationShadeWindowView) {
         mHeadsUpManager = headsUpManager;
         mStatusBar = statusBar;
-        mStatusBarWindowView = statusBarWindowView;
-        mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
-
-        initResources();
+        mNotificationShadeWindowView = notificationShadeWindowView;
+        mNotificationShadeWindowController =
+                Dependency.get(NotificationShadeWindowController.class);
 
         mBubbleController.setBubbleStateChangeListener((hasBubbles) -> {
             updateTouchableRegion();
         });
 
-        mStatusBarWindowController.setForcePluginOpenListener((forceOpen) -> {
+        mNotificationShadeWindowController.setForcePluginOpenListener((forceOpen) -> {
             updateTouchableRegion();
         });
         Dependency.get(ConfigurationController.class).addCallback(this);
+        if (mNotificationShadeWindowView != null) {
+            mNotificationPanelView = mNotificationShadeWindowView.findViewById(
+                    R.id.notification_panel);
+        }
     }
 
     /**
      * Set the touchable portion of the status bar based on what elements are visible.
      */
     public void updateTouchableRegion() {
-        boolean hasCutoutInset = (mStatusBarWindowView != null)
-                && (mStatusBarWindowView.getRootWindowInsets() != null)
-                && (mStatusBarWindowView.getRootWindowInsets().getDisplayCutout() != null);
+        boolean hasCutoutInset = (mNotificationShadeWindowView != null)
+                && (mNotificationShadeWindowView.getRootWindowInsets() != null)
+                && (mNotificationShadeWindowView.getRootWindowInsets().getDisplayCutout() != null);
         boolean shouldObserve =
                 mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpManager.isHeadsUpGoingAway()
                         || mBubbleController.hasBubbles()
                         || mForceCollapsedUntilLayout
                         || hasCutoutInset
-                        || mStatusBarWindowController.getForcePluginOpen();
+                        || mNotificationShadeWindowController.getForcePluginOpen();
         if (shouldObserve == mShouldAdjustInsets) {
             return;
         }
 
         if (shouldObserve) {
-            mStatusBarWindowView.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
-            mStatusBarWindowView.requestLayout();
+            mNotificationShadeWindowView.getViewTreeObserver()
+                    .addOnComputeInternalInsetsListener(this);
+            mNotificationShadeWindowView.requestLayout();
         } else {
-            mStatusBarWindowView.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+            mNotificationShadeWindowView.getViewTreeObserver()
+                    .removeOnComputeInternalInsetsListener(this);
         }
         mShouldAdjustInsets = shouldObserve;
     }
@@ -100,19 +100,20 @@
      * Calls {@code updateTouchableRegion()} after a layout pass completes.
      */
     public void updateTouchableRegionAfterLayout() {
-        mForceCollapsedUntilLayout = true;
-        mStatusBarWindowView.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) {
-                if (mStatusBarWindowView.getHeight() <= mStatusBarHeight) {
-                    mStatusBarWindowView.removeOnLayoutChangeListener(this);
-                    mForceCollapsedUntilLayout = false;
-                    updateTouchableRegion();
+        if (mNotificationPanelView != null) {
+            mForceCollapsedUntilLayout = true;
+            mNotificationPanelView.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) {
+                    if (!mNotificationPanelView.isVisibleToUser()) {
+                        mNotificationPanelView.removeOnLayoutChangeListener(this);
+                        mForceCollapsedUntilLayout = false;
+                        updateTouchableRegion();
+                    }
                 }
-            }
-        });
+            });
+        }
     }
 
     /**
@@ -145,25 +146,4 @@
             info.touchableRegion.union(bubbleRect);
         }
     }
-
-    @Override
-    public void onConfigChanged(Configuration newConfig) {
-        initResources();
-    }
-
-    @Override
-    public void onDensityOrFontScaleChanged() {
-        initResources();
-    }
-
-    @Override
-    public void onOverlayChanged() {
-        initResources();
-    }
-
-    private void initResources() {
-        Resources resources = mContext.getResources();
-        mStatusBarHeight = resources.getDimensionPixelSize(
-                com.android.internal.R.dimen.status_bar_height);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index ce498a3..fb30bde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,55 +11,25 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar.phone;
 
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
 
-import static com.android.systemui.DejankUtils.whitelistIpcs;
-import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
-
-import android.app.IActivityManager;
 import android.content.Context;
-import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.os.Binder;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.os.Trace;
 import android.util.Log;
-import android.view.Display;
 import android.view.Gravity;
-import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
 
-import com.android.systemui.Dumpable;
-import com.android.systemui.R;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.RemoteInputController.Callback;
-import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-
-import com.google.android.collect.Lists;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -68,101 +38,36 @@
  * Encapsulates all logic for the status bar window state management.
  */
 @Singleton
-public class StatusBarWindowController implements Callback, Dumpable, ConfigurationListener {
-
+public class StatusBarWindowController {
     private static final String TAG = "StatusBarWindowController";
     private static final boolean DEBUG = false;
 
     private final Context mContext;
     private final WindowManager mWindowManager;
-    private final IActivityManager mActivityManager;
-    private final DozeParameters mDozeParameters;
-    private final LayoutParams mLpChanged;
-    private final boolean mKeyguardScreenRotation;
-    private final long mLockScreenDisplayTimeout;
-    private final Display.Mode mKeyguardDisplayMode;
-    private final KeyguardBypassController mKeyguardBypassController;
-    private ViewGroup mStatusBarView;
-    private LayoutParams mLp;
-    private boolean mHasTopUi;
-    private boolean mHasTopUiChanged;
-    private int mBarHeight = -1;
-    private float mScreenBrightnessDoze;
-    private final State mCurrentState = new State();
-    private OtherwisedCollapsedListener mListener;
-    private ForcePluginOpenListener mForcePluginOpenListener;
-    private final ArrayList<WeakReference<StatusBarWindowCallback>>
-            mCallbacks = Lists.newArrayList();
-
-    private final SysuiColorExtractor mColorExtractor;
     private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
     private final Resources mResources;
+    private int mBarHeight = -1;
+    private final State mCurrentState = new State();
+
+    private ViewGroup mStatusBarView;
+    private WindowManager.LayoutParams mLp;
+    private final WindowManager.LayoutParams mLpChanged;
 
     @Inject
     public StatusBarWindowController(Context context, WindowManager windowManager,
-            IActivityManager activityManager, DozeParameters dozeParameters,
-            StatusBarStateController statusBarStateController,
-            ConfigurationController configurationController,
-            KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor,
             SuperStatusBarViewFactory superStatusBarViewFactory,
             @Main Resources resources) {
         mContext = context;
         mWindowManager = windowManager;
-        mActivityManager = activityManager;
-        mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
-        mDozeParameters = dozeParameters;
-        mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
-        mLpChanged = new LayoutParams();
-        mKeyguardBypassController = keyguardBypassController;
-        mColorExtractor = colorExtractor;
         mSuperStatusBarViewFactory = superStatusBarViewFactory;
         mStatusBarView = mSuperStatusBarViewFactory.getStatusBarWindowView();
+        mLpChanged = new WindowManager.LayoutParams();
         mResources = resources;
 
         if (mBarHeight < 0) {
             mBarHeight = mResources.getDimensionPixelSize(
                     com.android.internal.R.dimen.status_bar_height);
         }
-
-        mLockScreenDisplayTimeout = context.getResources()
-                .getInteger(R.integer.config_lockScreenDisplayTimeout);
-        ((SysuiStatusBarStateController) statusBarStateController)
-                .addCallback(mStateListener,
-                        SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
-        configurationController.addCallback(this);
-
-        Display.Mode[] supportedModes = context.getDisplay().getSupportedModes();
-        Display.Mode currentMode = context.getDisplay().getMode();
-        // Running on the highest frame rate available can be expensive.
-        // Let's specify a preferred refresh rate, and allow higher FPS only when we
-        // know that we're not falsing (because we unlocked.)
-        int keyguardRefreshRate = context.getResources()
-                .getInteger(R.integer.config_keyguardRefreshRate);
-        // Find supported display mode with the same resolution and requested refresh rate.
-        mKeyguardDisplayMode = Arrays.stream(supportedModes).filter(mode ->
-                (int) mode.getRefreshRate() == keyguardRefreshRate
-                        && mode.getPhysicalWidth() == currentMode.getPhysicalWidth()
-                        && mode.getPhysicalHeight() == currentMode.getPhysicalHeight())
-                .findFirst().orElse(null);
-    }
-
-    /**
-     * Register to receive notifications about status bar window state changes.
-     */
-    public void registerCallback(StatusBarWindowCallback callback) {
-        // Prevent adding duplicate callbacks
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            if (mCallbacks.get(i).get() == callback) {
-                return;
-            }
-        }
-        mCallbacks.add(new WeakReference<StatusBarWindowCallback>(callback));
-    }
-
-    private boolean shouldEnableKeyguardScreenRotation() {
-        Resources res = mContext.getResources();
-        return SystemProperties.getBoolean("lockscreen.rot_override", false)
-                || res.getBoolean(R.bool.config_enableLockScreenRotation);
     }
 
     public int getStatusBarHeight() {
@@ -192,574 +97,51 @@
         // Now that the status bar window encompasses the sliding panel and its
         // translucent backdrop, the entire thing is made TRANSLUCENT and is
         // hardware-accelerated.
-        mLp = new LayoutParams(
+        mLp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 mBarHeight,
-                LayoutParams.TYPE_STATUS_BAR,
-                LayoutParams.FLAG_NOT_FOCUSABLE
-                        | LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
-                        | LayoutParams.FLAG_SPLIT_TOUCH
-                        | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                        | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                 PixelFormat.TRANSLUCENT);
         mLp.token = new Binder();
         mLp.gravity = Gravity.TOP;
-        mLp.setFitWindowInsetsTypes(0 /* types */);
-        mLp.softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
         mLp.setTitle("StatusBar");
         mLp.packageName = mContext.getPackageName();
         mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
         mWindowManager.addView(mStatusBarView, mLp);
         mLpChanged.copyFrom(mLp);
-        onThemeChanged();
     }
 
-    public ViewGroup getStatusBarView() {
-        return mStatusBarView;
+    /** Set force status bar visible. */
+    public void setForceStatusBarVisible(boolean forceStatusBarVisible) {
+        mCurrentState.mForceStatusBarVisible = forceStatusBarVisible;
+        apply(mCurrentState);
     }
 
-    public void setDozeScreenBrightness(int value) {
-        mScreenBrightnessDoze = value / 255f;
-    }
-
-    private void setKeyguardDark(boolean dark) {
-        int vis = mStatusBarView.getSystemUiVisibility();
-        if (dark) {
-            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
-            vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        } else {
-            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
-            vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        }
-        mStatusBarView.setSystemUiVisibility(vis);
-    }
-
-    private void applyKeyguardFlags(State state) {
-        if (state.keyguardShowing) {
-            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_KEYGUARD;
-        } else {
-            mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_KEYGUARD;
-        }
-
-        final boolean scrimsOccludingWallpaper =
-                state.scrimsVisibility == ScrimController.OPAQUE;
-        final boolean keyguardOrAod = state.keyguardShowing
-                || (state.dozing && mDozeParameters.getAlwaysOn());
-        if (keyguardOrAod && !state.backdropShowing && !scrimsOccludingWallpaper) {
-            mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;
-        } else {
-            mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;
-        }
-
-        if (state.dozing) {
-            mLpChanged.privateFlags |= LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-        } else {
-            mLpChanged.privateFlags &= ~LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-        }
-
-        if (mKeyguardDisplayMode != null) {
-            boolean bypassOnKeyguard = mKeyguardBypassController.getBypassEnabled()
-                    && state.statusBarState == StatusBarState.KEYGUARD && !state.keyguardFadingAway
-                    && !state.keyguardGoingAway;
-            if (state.dozing || bypassOnKeyguard) {
-                mLpChanged.preferredDisplayModeId = mKeyguardDisplayMode.getModeId();
-            } else {
-                mLpChanged.preferredDisplayModeId = 0;
-            }
-            Trace.setCounter("display_mode_id", mLpChanged.preferredDisplayModeId);
-        }
-    }
-
-    private void adjustScreenOrientation(State state) {
-        if (state.isKeyguardShowingAndNotOccluded() || state.dozing) {
-            if (mKeyguardScreenRotation) {
-                mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
-            } else {
-                mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-            }
-        } else {
-            mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-        }
-    }
-
-    private void applyFocusableFlag(State state) {
-        boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
-        if (state.bouncerShowing && (state.keyguardOccluded || state.keyguardNeedsInput)
-                || ENABLE_REMOTE_INPUT && state.remoteInputActive
-                || state.bubbleExpanded) {
-            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
-            mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-        } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
-            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
-            mLpChanged.flags |= LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-        } else {
-            mLpChanged.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
-            mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-        }
-
-        mLpChanged.softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-    }
-
-    private void applyForceShowNavigationFlag(State state) {
-        if (state.panelExpanded || state.bouncerShowing
-                || ENABLE_REMOTE_INPUT && state.remoteInputActive) {
-            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
-        } else {
-            mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
-        }
-    }
-
-    private void applyHeight(State state) {
-        boolean expanded = isExpanded(state);
-        if (state.forcePluginOpen) {
-            if (mListener != null) {
-                mListener.setWouldOtherwiseCollapse(expanded);
-            }
-            expanded = true;
-        }
-        if (expanded) {
-            mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT;
-        } else {
-            mLpChanged.height = mBarHeight;
-        }
-    }
-
-    private boolean isExpanded(State state) {
-        return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
-                || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
-                || state.headsUpShowing || state.bubblesShowing
-                || state.scrimsVisibility != ScrimController.TRANSPARENT);
-    }
-
-    private void applyFitsSystemWindows(State state) {
-        boolean fitsSystemWindows = !state.isKeyguardShowingAndNotOccluded();
-        if (mStatusBarView != null && mStatusBarView.getFitsSystemWindows() != fitsSystemWindows) {
-            mStatusBarView.setFitsSystemWindows(fitsSystemWindows);
-            mStatusBarView.requestApplyInsets();
-        }
-    }
-
-    private void applyUserActivityTimeout(State state) {
-        if (state.isKeyguardShowingAndNotOccluded()
-                && state.statusBarState == StatusBarState.KEYGUARD
-                && !state.qsExpanded) {
-            mLpChanged.userActivityTimeout = state.bouncerShowing
-                    ? KeyguardViewMediator.AWAKE_INTERVAL_BOUNCER_MS : mLockScreenDisplayTimeout;
-        } else {
-            mLpChanged.userActivityTimeout = -1;
-        }
-    }
-
-    private void applyInputFeatures(State state) {
-        if (state.isKeyguardShowingAndNotOccluded()
-                && state.statusBarState == StatusBarState.KEYGUARD
-                && !state.qsExpanded && !state.forceUserActivity) {
-            mLpChanged.inputFeatures |=
-                    LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
-        } else {
-            mLpChanged.inputFeatures &=
-                    ~LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
-        }
-    }
-
-    private void applyStatusBarColorSpaceAgnosticFlag(State state) {
-        if (!isExpanded(state)) {
-            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
-        } else {
-            mLpChanged.privateFlags &=
-                    ~LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
-        }
+    private void applyHeight() {
+        mLpChanged.height = mBarHeight;
     }
 
     private void apply(State state) {
-        applyKeyguardFlags(state);
         applyForceStatusBarVisibleFlag(state);
-        applyFocusableFlag(state);
-        applyForceShowNavigationFlag(state);
-        adjustScreenOrientation(state);
-        applyHeight(state);
-        applyUserActivityTimeout(state);
-        applyInputFeatures(state);
-        applyFitsSystemWindows(state);
-        applyModalFlag(state);
-        applyBrightness(state);
-        applyHasTopUi(state);
-        applyNotTouchable(state);
-        applyStatusBarColorSpaceAgnosticFlag(state);
+        applyHeight();
         if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
             mWindowManager.updateViewLayout(mStatusBarView, mLp);
         }
-        if (mHasTopUi != mHasTopUiChanged) {
-            whitelistIpcs(() -> {
-                try {
-                    mActivityManager.setHasTopUi(mHasTopUiChanged);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to call setHasTopUi", e);
-                }
-                mHasTopUi = mHasTopUiChanged;
-            });
-        }
-        notifyStateChangedCallbacks();
-    }
-
-    public void notifyStateChangedCallbacks() {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            StatusBarWindowCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onStateChanged(mCurrentState.keyguardShowing,
-                        mCurrentState.keyguardOccluded,
-                        mCurrentState.bouncerShowing);
-            }
-        }
-    }
-
-    private void applyForceStatusBarVisibleFlag(State state) {
-        if (state.forceStatusBarVisible || state.forcePluginOpen) {
-            mLpChanged.privateFlags |= WindowManager
-                    .LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
-        } else {
-            mLpChanged.privateFlags
-                    &= ~LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
-        }
-    }
-
-    private void applyModalFlag(State state) {
-        if (state.headsUpShowing) {
-            mLpChanged.flags |= LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        } else {
-            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        }
-    }
-
-    private void applyBrightness(State state) {
-        if (state.forceDozeBrightness) {
-            mLpChanged.screenBrightness = mScreenBrightnessDoze;
-        } else {
-            mLpChanged.screenBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
-        }
-    }
-
-    private void applyHasTopUi(State state) {
-        mHasTopUiChanged = state.forceHasTopUi || isExpanded(state);
-    }
-
-    private void applyNotTouchable(State state) {
-        if (state.notTouchable) {
-            mLpChanged.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
-        } else {
-            mLpChanged.flags &= ~LayoutParams.FLAG_NOT_TOUCHABLE;
-        }
-    }
-
-    public void setKeyguardShowing(boolean showing) {
-        mCurrentState.keyguardShowing = showing;
-        apply(mCurrentState);
-    }
-
-    public void setKeyguardOccluded(boolean occluded) {
-        mCurrentState.keyguardOccluded = occluded;
-        apply(mCurrentState);
-    }
-
-    public void setKeyguardNeedsInput(boolean needsInput) {
-        mCurrentState.keyguardNeedsInput = needsInput;
-        apply(mCurrentState);
-    }
-
-    public void setPanelVisible(boolean visible) {
-        mCurrentState.panelVisible = visible;
-        mCurrentState.statusBarFocusable = visible;
-        apply(mCurrentState);
-    }
-
-    public void setStatusBarFocusable(boolean focusable) {
-        mCurrentState.statusBarFocusable = focusable;
-        apply(mCurrentState);
-    }
-
-    public void setBouncerShowing(boolean showing) {
-        mCurrentState.bouncerShowing = showing;
-        apply(mCurrentState);
-    }
-
-    public void setBackdropShowing(boolean showing) {
-        mCurrentState.backdropShowing = showing;
-        apply(mCurrentState);
-    }
-
-    public void setKeyguardFadingAway(boolean keyguardFadingAway) {
-        mCurrentState.keyguardFadingAway = keyguardFadingAway;
-        apply(mCurrentState);
-    }
-
-    public void setQsExpanded(boolean expanded) {
-        mCurrentState.qsExpanded = expanded;
-        apply(mCurrentState);
-    }
-
-    public void setForceUserActivity(boolean forceUserActivity) {
-        mCurrentState.forceUserActivity = forceUserActivity;
-        apply(mCurrentState);
-    }
-
-    public void setScrimsVisibility(int scrimsVisibility) {
-        mCurrentState.scrimsVisibility = scrimsVisibility;
-        apply(mCurrentState);
-    }
-
-    public void setHeadsUpShowing(boolean showing) {
-        mCurrentState.headsUpShowing = showing;
-        apply(mCurrentState);
-    }
-
-    public void setWallpaperSupportsAmbientMode(boolean supportsAmbientMode) {
-        mCurrentState.wallpaperSupportsAmbientMode = supportsAmbientMode;
-        apply(mCurrentState);
-    }
-
-    /**
-     * @param state The {@link StatusBarStateController} of the status bar.
-     */
-    private void setStatusBarState(int state) {
-        mCurrentState.statusBarState = state;
-        apply(mCurrentState);
-    }
-
-    public void setForceStatusBarVisible(boolean forceStatusBarVisible) {
-        mCurrentState.forceStatusBarVisible = forceStatusBarVisible;
-        apply(mCurrentState);
-    }
-
-    /**
-     * Force the window to be collapsed, even if it should theoretically be expanded.
-     * Used for when a heads-up comes in but we still need to wait for the touchable regions to
-     * be computed.
-     */
-    public void setForceWindowCollapsed(boolean force) {
-        mCurrentState.forceCollapsed = force;
-        apply(mCurrentState);
-    }
-
-    public void setPanelExpanded(boolean isExpanded) {
-        mCurrentState.panelExpanded = isExpanded;
-        apply(mCurrentState);
-    }
-
-    @Override
-    public void onRemoteInputActive(boolean remoteInputActive) {
-        mCurrentState.remoteInputActive = remoteInputActive;
-        apply(mCurrentState);
-    }
-
-    /**
-     * Set whether the screen brightness is forced to the value we use for doze mode by the status
-     * bar window.
-     */
-    public void setForceDozeBrightness(boolean forceDozeBrightness) {
-        mCurrentState.forceDozeBrightness = forceDozeBrightness;
-        apply(mCurrentState);
-    }
-
-    public void setDozing(boolean dozing) {
-        mCurrentState.dozing = dozing;
-        apply(mCurrentState);
-    }
-
-    public void setForcePluginOpen(boolean forcePluginOpen) {
-        mCurrentState.forcePluginOpen = forcePluginOpen;
-        apply(mCurrentState);
-        if (mForcePluginOpenListener != null) {
-            mForcePluginOpenListener.onChange(forcePluginOpen);
-        }
-    }
-
-    /**
-     * The forcePluginOpen state for the status bar.
-     */
-    public boolean getForcePluginOpen() {
-        return mCurrentState.forcePluginOpen;
-    }
-
-    public void setNotTouchable(boolean notTouchable) {
-        mCurrentState.notTouchable = notTouchable;
-        apply(mCurrentState);
-    }
-
-    /**
-     * Sets whether there are bubbles showing on the screen.
-     */
-    public void setBubblesShowing(boolean bubblesShowing) {
-        mCurrentState.bubblesShowing = bubblesShowing;
-        apply(mCurrentState);
-    }
-
-    /**
-     * The bubbles showing state for the status bar.
-     */
-    public boolean getBubblesShowing() {
-        return mCurrentState.bubblesShowing;
-    }
-
-    /**
-     * Sets if there is a bubble being expanded on the screen.
-     */
-    public void setBubbleExpanded(boolean bubbleExpanded) {
-        mCurrentState.bubbleExpanded = bubbleExpanded;
-        apply(mCurrentState);
-    }
-
-    /**
-     * Whether the bubble is shown in expanded state for the status bar.
-     */
-    public boolean getBubbleExpanded() {
-        return mCurrentState.bubbleExpanded;
-    }
-
-    /**
-     * Whether the status bar panel is expanded or not.
-     */
-    public boolean getPanelExpanded() {
-        return mCurrentState.panelExpanded;
-    }
-
-    public void setStateListener(OtherwisedCollapsedListener listener) {
-        mListener = listener;
-    }
-
-    public void setForcePluginOpenListener(ForcePluginOpenListener listener) {
-        mForcePluginOpenListener = listener;
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("StatusBarWindowController:");
-        pw.println("  mKeyguardDisplayMode=" + mKeyguardDisplayMode);
-        pw.println(mCurrentState);
-    }
-
-    public boolean isShowingWallpaper() {
-        return !mCurrentState.backdropShowing;
-    }
-
-    @Override
-    public void onThemeChanged() {
-        if (mStatusBarView == null) {
-            return;
-        }
-
-        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
-        // Make sure we have the correct navbar/statusbar colors.
-        setKeyguardDark(useDarkText);
-    }
-
-    /**
-     * When keyguard will be dismissed but didn't start animation yet.
-     */
-    public void setKeyguardGoingAway(boolean goingAway) {
-        mCurrentState.keyguardGoingAway = goingAway;
-        apply(mCurrentState);
-    }
-
-    public boolean getForceHasTopUi() {
-        return mCurrentState.forceHasTopUi;
-    }
-
-    public void setForceHasTopUi(boolean forceHasTopUi) {
-        mCurrentState.forceHasTopUi = forceHasTopUi;
-        apply(mCurrentState);
     }
 
     private static class State {
-        boolean keyguardShowing;
-        boolean keyguardOccluded;
-        boolean keyguardNeedsInput;
-        boolean panelVisible;
-        boolean panelExpanded;
-        boolean statusBarFocusable;
-        boolean bouncerShowing;
-        boolean keyguardFadingAway;
-        boolean keyguardGoingAway;
-        boolean qsExpanded;
-        boolean headsUpShowing;
-        boolean forceStatusBarVisible;
-        boolean forceCollapsed;
-        boolean forceDozeBrightness;
-        boolean forceUserActivity;
-        boolean backdropShowing;
-        boolean wallpaperSupportsAmbientMode;
-        boolean notTouchable;
-        boolean bubblesShowing;
-        boolean bubbleExpanded;
-        boolean forceHasTopUi;
-
-        /**
-         * The {@link StatusBar} state from the status bar.
-         */
-        int statusBarState;
-
-        boolean remoteInputActive;
-        boolean forcePluginOpen;
-        boolean dozing;
-        int scrimsVisibility;
-
-        private boolean isKeyguardShowingAndNotOccluded() {
-            return keyguardShowing && !keyguardOccluded;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder result = new StringBuilder();
-            String newLine = "\n";
-            result.append("Window State {");
-            result.append(newLine);
-
-            Field[] fields = this.getClass().getDeclaredFields();
-
-            // Print field names paired with their values
-            for (Field field : fields) {
-                result.append("  ");
-                try {
-                    result.append(field.getName());
-                    result.append(": ");
-                    //requires access to private field:
-                    result.append(field.get(this));
-                } catch (IllegalAccessException ex) {
-                }
-                result.append(newLine);
-            }
-            result.append("}");
-
-            return result.toString();
-        }
+        boolean mForceStatusBarVisible;
     }
 
-    private final StateListener mStateListener = new StateListener() {
-        @Override
-        public void onStateChanged(int newState) {
-            setStatusBarState(newState);
+    private void applyForceStatusBarVisibleFlag(State state) {
+        if (state.mForceStatusBarVisible) {
+            mLpChanged.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
+        } else {
+            mLpChanged.privateFlags &= ~PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
         }
-
-        @Override
-        public void onDozingChanged(boolean isDozing) {
-            setDozing(isDozing);
-        }
-    };
-
-    /**
-     * Custom listener to pipe data back to plugins about whether or not the status bar would be
-     * collapsed if not for the plugin.
-     * TODO: Find cleaner way to do this.
-     */
-    public interface OtherwisedCollapsedListener {
-        void setWouldOtherwiseCollapse(boolean otherwiseCollapse);
-    }
-
-    /**
-     * Listener to indicate forcePluginOpen has changed
-     */
-    public interface ForcePluginOpenListener {
-        /**
-         * Called when mState.forcePluginOpen is changed
-         */
-        void onChange(boolean forceOpen);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 1e3c5d6..da5df6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,599 +16,19 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.annotation.ColorInt;
-import android.annotation.DrawableRes;
-import android.annotation.LayoutRes;
 import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Insets;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
 import android.util.AttributeSet;
-import android.view.ActionMode;
-import android.view.DisplayCutout;
-import android.view.InputQueue;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.Window;
-import android.view.WindowInsets;
-import android.view.WindowInsetsController;
 import android.widget.FrameLayout;
 
-import com.android.internal.view.FloatingActionMode;
-import com.android.internal.widget.FloatingToolbar;
-import com.android.systemui.R;
-
 /**
- * Combined status bar and notification panel view. Also holding backdrop and scrims.
+ * Status bar view.
  */
 public class StatusBarWindowView extends FrameLayout {
-    public static final String TAG = "StatusBarWindowView";
+
+    public static final String TAG = "PhoneStatusBarWindowView";
     public static final boolean DEBUG = StatusBar.DEBUG;
 
-    private int mRightInset = 0;
-    private int mLeftInset = 0;
-
-    // Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
-    // DecorView, but since this is a special window we have to roll our own.
-    private View mFloatingActionModeOriginatingView;
-    private ActionMode mFloatingActionMode;
-    private FloatingToolbar mFloatingToolbar;
-    private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
-
-    private InteractionEventHandler mInteractionEventHandler;
-
     public StatusBarWindowView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        setMotionEventSplittingEnabled(false);
     }
-
-    public NotificationPanelView getNotificationPanelView() {
-        return findViewById(R.id.notification_panel);
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
-        final Insets insets = windowInsets.getMaxInsets(WindowInsets.Type.systemBars());
-        if (getFitsSystemWindows()) {
-            boolean paddingChanged = insets.top != getPaddingTop()
-                    || insets.bottom != getPaddingBottom();
-
-            int rightCutout = 0;
-            int leftCutout = 0;
-            DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
-            if (displayCutout != null) {
-                leftCutout = displayCutout.getSafeInsetLeft();
-                rightCutout = displayCutout.getSafeInsetRight();
-            }
-
-            int targetLeft = Math.max(insets.left, leftCutout);
-            int targetRight = Math.max(insets.right, rightCutout);
-
-            // Super-special right inset handling, because scrims and backdrop need to ignore it.
-            if (targetRight != mRightInset || targetLeft != mLeftInset) {
-                mRightInset = targetRight;
-                mLeftInset = targetLeft;
-                applyMargins();
-            }
-            // Drop top inset, and pass through bottom inset.
-            if (paddingChanged) {
-                setPadding(0, 0, 0, 0);
-            }
-        } else {
-            if (mRightInset != 0 || mLeftInset != 0) {
-                mRightInset = 0;
-                mLeftInset = 0;
-                applyMargins();
-            }
-            boolean changed = getPaddingLeft() != 0
-                    || getPaddingRight() != 0
-                    || getPaddingTop() != 0
-                    || getPaddingBottom() != 0;
-            if (changed) {
-                setPadding(0, 0, 0, 0);
-            }
-        }
-        return windowInsets;
-    }
-
-    private void applyMargins() {
-        final int N = getChildCount();
-        for (int i = 0; i < N; i++) {
-            View child = getChildAt(i);
-            if (child.getLayoutParams() instanceof LayoutParams) {
-                LayoutParams lp = (LayoutParams) child.getLayoutParams();
-                if (!lp.ignoreRightInset
-                        && (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset)) {
-                    lp.rightMargin = mRightInset;
-                    lp.leftMargin = mLeftInset;
-                    child.requestLayout();
-                }
-            }
-        }
-    }
-
-    @Override
-    public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs);
-    }
-
-    @Override
-    protected FrameLayout.LayoutParams generateDefaultLayoutParams() {
-        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-    }
-
-    @Override
-    protected void onAttachedToWindow () {
-        super.onAttachedToWindow();
-        setWillNotDraw(!DEBUG);
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        if (mInteractionEventHandler.interceptMediaKey(event)) {
-            return true;
-        }
-
-        if (super.dispatchKeyEvent(event)) {
-            return true;
-        }
-
-        return mInteractionEventHandler.dispatchKeyEvent(event);
-    }
-
-    protected void setInteractionEventHandler(InteractionEventHandler listener) {
-        mInteractionEventHandler = listener;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        Boolean result = mInteractionEventHandler.handleDispatchTouchEvent(ev);
-
-        return result != null ? result : super.dispatchTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        boolean intercept = mInteractionEventHandler.shouldInterceptTouchEvent(ev);
-        if (!intercept) {
-            intercept = super.onInterceptTouchEvent(ev);
-        }
-        if (intercept) {
-            mInteractionEventHandler.didIntercept(ev);
-        }
-
-        return intercept;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean handled = mInteractionEventHandler.handleTouchEvent(ev);
-
-        if (!handled) {
-            handled = super.onTouchEvent(ev);
-        }
-
-        if (!handled) {
-            mInteractionEventHandler.didNotHandleTouchEvent(ev);
-        }
-
-        return handled;
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (DEBUG) {
-            Paint pt = new Paint();
-            pt.setColor(0x80FFFF00);
-            pt.setStrokeWidth(12.0f);
-            pt.setStyle(Paint.Style.STROKE);
-            canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), pt);
-        }
-    }
-
-    public class LayoutParams extends FrameLayout.LayoutParams {
-
-        public boolean ignoreRightInset;
-
-        public LayoutParams(int width, int height) {
-            super(width, height);
-        }
-
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-
-            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout);
-            ignoreRightInset = a.getBoolean(
-                    R.styleable.StatusBarWindowView_Layout_ignoreRightInset, false);
-            a.recycle();
-        }
-    }
-
-    @Override
-    public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback,
-            int type) {
-        if (type == ActionMode.TYPE_FLOATING) {
-            return startActionMode(originalView, callback, type);
-        }
-        return super.startActionModeForChild(originalView, callback, type);
-    }
-
-    private ActionMode createFloatingActionMode(
-            View originatingView, ActionMode.Callback2 callback) {
-        if (mFloatingActionMode != null) {
-            mFloatingActionMode.finish();
-        }
-        cleanupFloatingActionModeViews();
-        mFloatingToolbar = new FloatingToolbar(mFakeWindow);
-        final FloatingActionMode mode =
-                new FloatingActionMode(mContext, callback, originatingView, mFloatingToolbar);
-        mFloatingActionModeOriginatingView = originatingView;
-        mFloatingToolbarPreDrawListener =
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        mode.updateViewLocationInWindow();
-                        return true;
-                    }
-                };
-        return mode;
-    }
-
-    private void setHandledFloatingActionMode(ActionMode mode) {
-        mFloatingActionMode = mode;
-        mFloatingActionMode.invalidate();  // Will show the floating toolbar if necessary.
-        mFloatingActionModeOriginatingView.getViewTreeObserver()
-                .addOnPreDrawListener(mFloatingToolbarPreDrawListener);
-    }
-
-    private void cleanupFloatingActionModeViews() {
-        if (mFloatingToolbar != null) {
-            mFloatingToolbar.dismiss();
-            mFloatingToolbar = null;
-        }
-        if (mFloatingActionModeOriginatingView != null) {
-            if (mFloatingToolbarPreDrawListener != null) {
-                mFloatingActionModeOriginatingView.getViewTreeObserver()
-                        .removeOnPreDrawListener(mFloatingToolbarPreDrawListener);
-                mFloatingToolbarPreDrawListener = null;
-            }
-            mFloatingActionModeOriginatingView = null;
-        }
-    }
-
-    private ActionMode startActionMode(
-            View originatingView, ActionMode.Callback callback, int type) {
-        ActionMode.Callback2 wrappedCallback = new ActionModeCallback2Wrapper(callback);
-        ActionMode mode = createFloatingActionMode(originatingView, wrappedCallback);
-        if (mode != null && wrappedCallback.onCreateActionMode(mode, mode.getMenu())) {
-            setHandledFloatingActionMode(mode);
-        } else {
-            mode = null;
-        }
-        return mode;
-    }
-
-    private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
-        private final ActionMode.Callback mWrapped;
-
-        public ActionModeCallback2Wrapper(ActionMode.Callback wrapped) {
-            mWrapped = wrapped;
-        }
-
-        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            return mWrapped.onCreateActionMode(mode, menu);
-        }
-
-        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-            requestFitSystemWindows();
-            return mWrapped.onPrepareActionMode(mode, menu);
-        }
-
-        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-            return mWrapped.onActionItemClicked(mode, item);
-        }
-
-        public void onDestroyActionMode(ActionMode mode) {
-            mWrapped.onDestroyActionMode(mode);
-            if (mode == mFloatingActionMode) {
-                cleanupFloatingActionModeViews();
-                mFloatingActionMode = null;
-            }
-            requestFitSystemWindows();
-        }
-
-        @Override
-        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
-            if (mWrapped instanceof ActionMode.Callback2) {
-                ((ActionMode.Callback2) mWrapped).onGetContentRect(mode, view, outRect);
-            } else {
-                super.onGetContentRect(mode, view, outRect);
-            }
-        }
-    }
-
-    interface InteractionEventHandler {
-        /**
-         * Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer
-         * to the super method.
-         */
-        Boolean handleDispatchTouchEvent(MotionEvent ev);
-
-        /**
-         * Returns if the view should intercept the touch event.
-         *
-         * The touch event may still be interecepted if
-         * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)} decides to do so.
-         */
-        boolean shouldInterceptTouchEvent(MotionEvent ev);
-
-        /**
-         * Called when the view decides to intercept the touch event.
-         */
-        void didIntercept(MotionEvent ev);
-
-        boolean handleTouchEvent(MotionEvent ev);
-
-        void didNotHandleTouchEvent(MotionEvent ev);
-
-        boolean interceptMediaKey(KeyEvent event);
-
-        boolean dispatchKeyEvent(KeyEvent event);
-    }
-
-    /**
-     * Minimal window to satisfy FloatingToolbar.
-     */
-    private Window mFakeWindow = new Window(mContext) {
-        @Override
-        public void takeSurface(SurfaceHolder.Callback2 callback) {
-        }
-
-        @Override
-        public void takeInputQueue(InputQueue.Callback callback) {
-        }
-
-        @Override
-        public boolean isFloating() {
-            return false;
-        }
-
-        @Override
-        public void alwaysReadCloseOnTouchAttr() {
-        }
-
-        @Override
-        public void setContentView(@LayoutRes int layoutResID) {
-        }
-
-        @Override
-        public void setContentView(View view) {
-        }
-
-        @Override
-        public void setContentView(View view, ViewGroup.LayoutParams params) {
-        }
-
-        @Override
-        public void addContentView(View view, ViewGroup.LayoutParams params) {
-        }
-
-        @Override
-        public void clearContentView() {
-        }
-
-        @Override
-        public View getCurrentFocus() {
-            return null;
-        }
-
-        @Override
-        public LayoutInflater getLayoutInflater() {
-            return null;
-        }
-
-        @Override
-        public void setTitle(CharSequence title) {
-        }
-
-        @Override
-        public void setTitleColor(@ColorInt int textColor) {
-        }
-
-        @Override
-        public void openPanel(int featureId, KeyEvent event) {
-        }
-
-        @Override
-        public void closePanel(int featureId) {
-        }
-
-        @Override
-        public void togglePanel(int featureId, KeyEvent event) {
-        }
-
-        @Override
-        public void invalidatePanelMenu(int featureId) {
-        }
-
-        @Override
-        public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) {
-            return false;
-        }
-
-        @Override
-        public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
-            return false;
-        }
-
-        @Override
-        public void closeAllPanels() {
-        }
-
-        @Override
-        public boolean performContextMenuIdentifierAction(int id, int flags) {
-            return false;
-        }
-
-        @Override
-        public void onConfigurationChanged(Configuration newConfig) {
-        }
-
-        @Override
-        public void setBackgroundDrawable(Drawable drawable) {
-        }
-
-        @Override
-        public void setFeatureDrawableResource(int featureId, @DrawableRes int resId) {
-        }
-
-        @Override
-        public void setFeatureDrawableUri(int featureId, Uri uri) {
-        }
-
-        @Override
-        public void setFeatureDrawable(int featureId, Drawable drawable) {
-        }
-
-        @Override
-        public void setFeatureDrawableAlpha(int featureId, int alpha) {
-        }
-
-        @Override
-        public void setFeatureInt(int featureId, int value) {
-        }
-
-        @Override
-        public void takeKeyEvents(boolean get) {
-        }
-
-        @Override
-        public boolean superDispatchKeyEvent(KeyEvent event) {
-            return false;
-        }
-
-        @Override
-        public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
-            return false;
-        }
-
-        @Override
-        public boolean superDispatchTouchEvent(MotionEvent event) {
-            return false;
-        }
-
-        @Override
-        public boolean superDispatchTrackballEvent(MotionEvent event) {
-            return false;
-        }
-
-        @Override
-        public boolean superDispatchGenericMotionEvent(MotionEvent event) {
-            return false;
-        }
-
-        @Override
-        public View getDecorView() {
-            return StatusBarWindowView.this;
-        }
-
-        @Override
-        public View peekDecorView() {
-            return null;
-        }
-
-        @Override
-        public Bundle saveHierarchyState() {
-            return null;
-        }
-
-        @Override
-        public void restoreHierarchyState(Bundle savedInstanceState) {
-        }
-
-        @Override
-        protected void onActive() {
-        }
-
-        @Override
-        public void setChildDrawable(int featureId, Drawable drawable) {
-        }
-
-        @Override
-        public void setChildInt(int featureId, int value) {
-        }
-
-        @Override
-        public boolean isShortcutKey(int keyCode, KeyEvent event) {
-            return false;
-        }
-
-        @Override
-        public void setVolumeControlStream(int streamType) {
-        }
-
-        @Override
-        public int getVolumeControlStream() {
-            return 0;
-        }
-
-        @Override
-        public int getStatusBarColor() {
-            return 0;
-        }
-
-        @Override
-        public void setStatusBarColor(@ColorInt int color) {
-        }
-
-        @Override
-        public int getNavigationBarColor() {
-            return 0;
-        }
-
-        @Override
-        public void setNavigationBarColor(@ColorInt int color) {
-        }
-
-        @Override
-        public void setDecorCaptionShade(int decorCaptionShade) {
-        }
-
-        @Override
-        public void setResizingCaptionDrawable(Drawable drawable) {
-        }
-
-        @Override
-        public void onMultiWindowModeChanged() {
-        }
-
-        @Override
-        public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        }
-
-        @Override
-        public void reportActivityRelaunched() {
-        }
-
-        @Override
-        public WindowInsetsController getInsetsController() {
-            return null;
-        }
-    };
-
 }
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
index 21d0bb8..802da3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
@@ -19,8 +19,9 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
-import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
@@ -41,7 +42,8 @@
      */
     @Subcomponent.Builder
     interface Builder {
-        @BindsInstance Builder statusBarWindowView(StatusBarWindowView statusBarWindowView);
+        @BindsInstance Builder statusBarWindowView(
+                NotificationShadeWindowView notificationShadeWindowView);
         StatusBarComponent build();
     }
 
@@ -54,10 +56,16 @@
     @interface StatusBarScope {}
 
     /**
+     * Creates a NotificationShadeWindowViewController.
+     */
+    @StatusBarScope
+    NotificationShadeWindowViewController getNotificationShadeWindowViewController();
+
+    /**
      * Creates a StatusBarWindowViewController.
      */
     @StatusBarScope
-    StatusBarWindowViewController getStatusBarWindowViewController();
+    StatusBarWindowController getStatusBarWindowController();
 
     /**
      * Creates a NotificationPanelViewController.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 20bd51d..37d8c9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.phone.dagger;
 
 import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 
 import dagger.Module;
 import dagger.Provides;
@@ -28,8 +28,8 @@
     @Provides
     @StatusBarComponent.StatusBarScope
     public static NotificationPanelView getNotificationPanelView(
-            StatusBarWindowView statusBarWindowView) {
-        return statusBarWindowView.getNotificationPanelView();
+            NotificationShadeWindowView notificationShadeWindowView) {
+        return notificationShadeWindowView.getNotificationPanelView();
     }
 
 }
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 625d884..d62da10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -25,7 +25,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 
 import java.util.Objects;
 import java.util.function.Consumer;
@@ -36,14 +36,14 @@
 public class BrightnessMirrorController
         implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> {
 
-    private final StatusBarWindowView mStatusBarWindow;
+    private final NotificationShadeWindowView mStatusBarWindow;
     private final Consumer<Boolean> mVisibilityCallback;
     private final NotificationPanelViewController mNotificationPanel;
     private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
     private final int[] mInt2Cache = new int[2];
     private View mBrightnessMirror;
 
-    public BrightnessMirrorController(StatusBarWindowView statusBarWindow,
+    public BrightnessMirrorController(NotificationShadeWindowView statusBarWindow,
             NotificationPanelViewController notificationPanelViewController,
             @NonNull Consumer<Boolean> visibilityCallback) {
         mStatusBarWindow = statusBarWindow;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 4f0af9e..759bad4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -298,7 +298,7 @@
             mShowSeconds = TunerService.parseIntegerSwitch(newValue, false);
             updateShowSeconds();
         } else {
-            setClockVisibleByUser(!StatusBarIconController.getIconBlacklist(newValue)
+            setClockVisibleByUser(!StatusBarIconController.getIconBlacklist(getContext(), newValue)
                     .contains("clock"));
             updateClockVisibility();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
index 905b9a3..66372c3 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
@@ -64,7 +64,7 @@
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
-            mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
+            mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
             mBatteryEnabled = !mBlacklist.contains(mBattery);
         }
         if (!mHasSetValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
index a526603..f7d0c9f 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
@@ -61,7 +61,7 @@
     public void onTuningChanged(String key, String newValue) {
         if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
             mReceivedClock = true;
-            mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
+            mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
             mClockEnabled = !mBlacklist.contains(mClock);
         } else if (Clock.CLOCK_SECONDS.equals(key)) {
             mReceivedSeconds = true;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index 6f23e20..de8ccfa 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -57,7 +57,7 @@
         if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
             return;
         }
-        mBlacklist = StatusBarIconController.getIconBlacklist(newValue);
+        mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
         setChecked(!mBlacklist.contains(getKey()));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 19f0ba2..142fdc2 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -117,7 +117,7 @@
             String blacklistStr = getValue(StatusBarIconController.ICON_BLACKLIST);
             if (blacklistStr != null) {
                 ArraySet<String> iconBlacklist =
-                        StatusBarIconController.getIconBlacklist(blacklistStr);
+                        StatusBarIconController.getIconBlacklist(mContext, blacklistStr);
 
                 iconBlacklist.add("rotate");
                 iconBlacklist.add("headset");
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt b/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt
new file mode 100644
index 0000000..ecd3afd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/FloatProperties.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.animation
+
+import android.graphics.Rect
+import android.graphics.RectF
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+
+/**
+ * Helpful extra properties to use with the [PhysicsAnimator]. These allow you to animate objects
+ * such as [Rect] and [RectF].
+ *
+ * There are additional, more basic properties available in [DynamicAnimation].
+ */
+class FloatProperties {
+    companion object {
+        /**
+         * Represents the x-coordinate of a [Rect]. Typically used to animate moving a Rect
+         * horizontally.
+         *
+         * This property's getter returns [Rect.left], and its setter uses [Rect.offsetTo], which
+         * sets [Rect.left] to the new value and offsets [Rect.right] so that the width of the Rect
+         * does not change.
+         */
+        @JvmField
+        val RECT_X = object : FloatPropertyCompat<Rect>("RectX") {
+            override fun setValue(rect: Rect?, value: Float) {
+                rect?.offsetTo(value.toInt(), rect.top)
+            }
+
+            override fun getValue(rect: Rect?): Float {
+                return rect?.left?.toFloat() ?: -Float.MAX_VALUE
+            }
+        }
+
+        /**
+         * Represents the y-coordinate of a [Rect]. Typically used to animate moving a Rect
+         * vertically.
+         *
+         * This property's getter returns [Rect.top], and its setter uses [Rect.offsetTo], which
+         * sets [Rect.top] to the new value and offsets [Rect.bottom] so that the height of the Rect
+         * does not change.
+         */
+        @JvmField
+        val RECT_Y = object : FloatPropertyCompat<Rect>("RectY") {
+            override fun setValue(rect: Rect?, value: Float) {
+                rect?.offsetTo(rect.left, value.toInt())
+            }
+
+            override fun getValue(rect: Rect?): Float {
+                return rect?.top?.toFloat() ?: -Float.MAX_VALUE
+            }
+        }
+
+        /**
+         * Represents the x-coordinate of a [RectF]. Typically used to animate moving a RectF
+         * horizontally.
+         *
+         * This property's getter returns [RectF.left], and its setter uses [RectF.offsetTo], which
+         * sets [RectF.left] to the new value and offsets [RectF.right] so that the width of the
+         * RectF does not change.
+         */
+        @JvmField
+        val RECTF_X = object : FloatPropertyCompat<RectF>("RectFX") {
+            override fun setValue(rect: RectF?, value: Float) {
+                rect?.offsetTo(value, rect.top)
+            }
+
+            override fun getValue(rect: RectF?): Float {
+                return rect?.left ?: -Float.MAX_VALUE
+            }
+        }
+
+        /**
+         * Represents the y-coordinate of a [RectF]. Typically used to animate moving a RectF
+         * vertically.
+         *
+         * This property's getter returns [RectF.top], and its setter uses [RectF.offsetTo], which
+         * sets [RectF.top] to the new value and offsets [RectF.bottom] so that the height of the
+         * RectF does not change.
+         */
+        @JvmField
+        val RECTF_Y = object : FloatPropertyCompat<RectF>("RectFY") {
+            override fun setValue(rect: RectF?, value: Float) {
+                rect?.offsetTo(rect.left, value)
+            }
+
+            override fun getValue(rect: RectF?): Float {
+                return rect?.top ?: -Float.MAX_VALUE
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
index 8a1759d..cfd77be 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
@@ -293,15 +293,19 @@
             val velocityToReachDestination = distanceToDestination *
                     (flingConfig.friction * FLING_FRICTION_SCALAR_MULTIPLIER)
 
-            // Try to use the provided start velocity, but use the required velocity to reach the
-            // destination if the provided velocity is insufficient.
-            val sufficientVelocity =
-                    if (distanceToDestination < 0)
-                        min(velocityToReachDestination, startVelocity)
-                    else
-                        max(velocityToReachDestination, startVelocity)
+            // If there's distance to cover, and the provided velocity is moving in the correct
+            // direction, ensure that the velocity is high enough to reach the destination.
+            // Otherwise, just use startVelocity - this means that the fling is at or out of bounds.
+            // The fling will immediately end and a spring will bring the object back into bounds
+            // with this startVelocity.
+            flingConfigCopy.startVelocity = when {
+                distanceToDestination > 0f && startVelocity >= 0f ->
+                    max(velocityToReachDestination, startVelocity)
+                distanceToDestination < 0f && startVelocity <= 0f ->
+                    min(velocityToReachDestination, startVelocity)
+                else -> startVelocity
+            }
 
-            flingConfigCopy.startVelocity = sufficientVelocity
             springConfigCopy.finalPosition = toAtLeast
         } else {
             flingConfigCopy.startVelocity = startVelocity
@@ -367,8 +371,17 @@
      * animation is explicitly canceled, use [addEndListener]. End listeners have an allEnded param,
      * which indicates that all relevant animations have ended.
      */
-    fun withEndActions(vararg endActions: EndAction): PhysicsAnimator<T> {
-        this.endActions.addAll(endActions)
+    fun withEndActions(vararg endActions: EndAction?): PhysicsAnimator<T> {
+        this.endActions.addAll(endActions.filterNotNull())
+        return this
+    }
+
+    /**
+     * Helper overload so that callers from Java can use Runnables or method references as end
+     * actions without having to explicitly return Unit.
+     */
+    fun withEndActions(vararg endActions: Runnable?): PhysicsAnimator<T> {
+        this.endActions.addAll(endActions.filterNotNull().map { it::run })
         return this
     }
 
@@ -416,8 +429,10 @@
                         max = max(currentValue, this.max)
                     }
 
-                    // Apply the configuration and start the animation.
+                    // Apply the configuration and start the animation. Since flings can't be
+                    // redirected while in motion, cancel it first.
                     getFlingAnimation(animatedProperty)
+                            .also { it.cancel() }
                             .also { flingConfig.applyToAnimation(it) }
                             .start()
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
index 02c7857..5aba013 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
@@ -39,10 +39,10 @@
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.SurfaceControlViewHost;
 import android.view.WindowlessWindowManager;
 
 import com.android.internal.os.IResultReceiver;
@@ -238,11 +238,13 @@
                 long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
                 Rect outVisibleInsets, Rect outStableInsets,
                 DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
-                SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
+                SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+                Point outSurfaceSize) {
             int res = super.relayout(window, seq, attrs, requestedWidth, requestedHeight,
                     viewVisibility, flags, frameNumber, outFrame, outOverscanInsets,
                     outContentInsets, outVisibleInsets, outStableInsets,
-                    cutout, mergedConfiguration, outSurfaceControl, outInsetsState);
+                    cutout, mergedConfiguration, outSurfaceControl, outInsetsState,
+                    outSurfaceSize);
             if (res != 0) {
                 return res;
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index ba264c0..5706bee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -53,6 +53,7 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.tuner.TunablePadding;
@@ -80,7 +81,8 @@
     private WindowManager mWindowManager;
     private FragmentService mFragmentService;
     private FragmentHostManager mFragmentHostManager;
-    private StatusBarWindowView mView;
+    private NotificationShadeWindowView mView;
+    private StatusBarWindowView mStatusBarWindowView;
     private TunablePaddingService mTunablePaddingService;
     private Handler mMainHandler;
     @Mock
@@ -99,9 +101,11 @@
         mFragmentService = mDependency.injectMockDependency(FragmentService.class);
 
         mWindowManager = mock(WindowManager.class);
-        mView = spy(new StatusBarWindowView(mContext, null));
+        mView = spy(new NotificationShadeWindowView(mContext, null));
+        mStatusBarWindowView = spy(new StatusBarWindowView(mContext, null));
         when(mStatusBarLazy.get()).thenReturn(mStatusBar);
-        when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
+        when(mStatusBar.getNotificationShadeWindowView()).thenReturn(mView);
+        when(mStatusBar.getStatusBarWindow()).thenReturn(mStatusBarWindowView);
 
         Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
         when(mWindowManager.getDefaultDisplay()).thenReturn(display);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index 162b16e..25bcb54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -18,19 +18,25 @@
 
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricPrompt;
 import android.os.Bundle;
+import android.os.UserManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
@@ -57,6 +63,7 @@
     private TestableAuthContainer mAuthContainer;
 
     private @Mock AuthDialogCallback mCallback;
+    private @Mock UserManager mUserManager;
 
     @Before
     public void setup() {
@@ -156,6 +163,18 @@
         verify(mAuthContainer.mFrameLayout).addView(mAuthContainer.mCredentialView);
     }
 
+    @Test
+    public void testCredentialViewUsesEffectiveUserId() {
+        final int dummyEffectiveUserId = 200;
+        when(mUserManager.getCredentialOwnerProfile(anyInt())).thenReturn(dummyEffectiveUserId);
+
+        initializeContainer(Authenticators.DEVICE_CREDENTIAL);
+        mAuthContainer.onAttachedToWindowInternal();
+        assertTrue(mAuthContainer.mCredentialView instanceof AuthCredentialPatternView);
+        assertEquals(dummyEffectiveUserId, mAuthContainer.mCredentialView.mEffectiveUserId);
+        assertEquals(Utils.CREDENTIAL_PATTERN, mAuthContainer.mCredentialView.mCredentialType);
+    }
+
     private void initializeContainer(int authenticators) {
         AuthContainerView.Config config = new AuthContainerView.Config();
         config.mContext = mContext;
@@ -211,5 +230,15 @@
         public int getAnimateCredentialStartDelayMs() {
             return 0;
         }
+
+        @Override
+        public UserManager getUserManager(Context context) {
+            return mUserManager;
+        }
+
+        @Override
+        public @Utils.CredentialType int getCredentialType(Context context, int effectiveUserId) {
+            return Utils.CREDENTIAL_PATTERN;
+        }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index c0e92e0..65399bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -20,7 +20,6 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
-import static junit.framework.TestCase.assertNotNull;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -292,6 +291,24 @@
     // Corner case tests
 
     @Test
+    public void testCancelAuthentication_whenCredentialConfirmed_doesntCrash() throws Exception {
+        // It's possible that before the client is notified that credential is confirmed, the client
+        // requests to cancel authentication.
+        //
+        // Test that the following sequence of events does not crash SystemUI:
+        // 1) Credential is confirmed
+        // 2) Client cancels authentication
+
+        showDialog(Authenticators.DEVICE_CREDENTIAL, BiometricPrompt.TYPE_NONE);
+        verify(mDialog1).show(any(), any());
+
+        mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED);
+        verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED);
+
+        mAuthController.hideAuthenticationDialog();
+    }
+
+    @Test
     public void testShowNewDialog_beforeOldDialogDismissed_SkipsAnimations() {
         showDialog(Authenticators.BIOMETRIC_WEAK, BiometricPrompt.TYPE_FACE);
         verify(mDialog1).show(any(), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index c3df3f6..04116ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -74,8 +74,8 @@
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -126,7 +126,7 @@
     private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
 
     private TestableBubbleController mBubbleController;
-    private StatusBarWindowController mStatusBarWindowController;
+    private NotificationShadeWindowController mNotificationShadeWindowController;
     private NotificationEntryListener mEntryListener;
     private NotificationRemoveInterceptor mRemoveInterceptor;
 
@@ -170,11 +170,11 @@
                 new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()));
 
         // Bubbles get added to status bar window view
-        mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
-                mActivityManager, mDozeParameters, mStatusBarStateController,
+        mNotificationShadeWindowController = new NotificationShadeWindowController(mContext,
+                mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
                 mConfigurationController, mKeyguardBypassController, mColorExtractor,
-                mSuperStatusBarViewFactory, mResources);
-        mStatusBarWindowController.attach();
+                mSuperStatusBarViewFactory);
+        mNotificationShadeWindowController.attach();
 
         // Need notifications for bubbles
         mNotificationTestHelper = new NotificationTestHelper(mContext, mDependency);
@@ -201,7 +201,7 @@
                 mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
         mBubbleData = new BubbleData(mContext);
         mBubbleController = new TestableBubbleController(mContext,
-                mStatusBarWindowController,
+                mNotificationShadeWindowController,
                 mStatusBarStateController,
                 mShadeController,
                 mBubbleData,
@@ -250,7 +250,7 @@
 
         mBubbleController.removeBubble(
                 mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
-        assertFalse(mStatusBarWindowController.getBubblesShowing());
+        assertFalse(mNotificationShadeWindowController.getBubblesShowing());
         assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()));
         verify(mNotificationEntryManager, times(2)).updateNotifications(anyString());
         verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
@@ -290,7 +290,7 @@
         assertTrue(mBubbleController.hasBubbles());
 
         mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
-        assertFalse(mStatusBarWindowController.getBubblesShowing());
+        assertFalse(mNotificationShadeWindowController.getBubblesShowing());
         verify(mNotificationEntryManager, times(3)).updateNotifications(any());
         assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()));
         assertNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().getKey()));
@@ -308,14 +308,14 @@
         assertTrue(mBubbleController.hasBubbles());
         assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
                 mRow.getEntry().getKey()));
-        assertFalse(mStatusBarWindowController.getBubbleExpanded());
+        assertFalse(mNotificationShadeWindowController.getBubbleExpanded());
 
         // Expand the stack
         BubbleStackView stackView = mBubbleController.getStackView();
         mBubbleController.expandStack();
         assertTrue(mBubbleController.isStackExpanded());
         verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
-        assertTrue(mStatusBarWindowController.getBubbleExpanded());
+        assertTrue(mNotificationShadeWindowController.getBubbleExpanded());
 
         // Make sure the notif is suppressed
         assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(
@@ -325,7 +325,7 @@
         mBubbleController.collapseStack();
         verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
         assertFalse(mBubbleController.isStackExpanded());
-        assertFalse(mStatusBarWindowController.getBubbleExpanded());
+        assertFalse(mNotificationShadeWindowController.getBubbleExpanded());
     }
 
     @Test
@@ -711,7 +711,7 @@
     static class TestableBubbleController extends BubbleController {
         // Let's assume surfaces can be synchronized immediately.
         TestableBubbleController(Context context,
-                StatusBarWindowController statusBarWindowController,
+                NotificationShadeWindowController notificationShadeWindowController,
                 StatusBarStateController statusBarStateController,
                 ShadeController shadeController,
                 BubbleData data,
@@ -723,7 +723,7 @@
                 NotificationEntryManager entryManager,
                 RemoteInputUriController remoteInputUriController) {
             super(context,
-                    statusBarWindowController, statusBarStateController, shadeController,
+                    notificationShadeWindowController, statusBarStateController, shadeController,
                     data, Runnable::run, configurationController, interruptionStateProvider,
                     zenModeController, lockscreenUserManager, groupManager, entryManager,
                     remoteInputUriController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 64fbc1b..acc30d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -36,8 +36,8 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
@@ -57,7 +57,7 @@
     private @Mock LockPatternUtils mLockPatternUtils;
     private @Mock KeyguardUpdateMonitor mUpdateMonitor;
     private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    private @Mock StatusBarWindowController mStatusBarWindowController;
+    private @Mock NotificationShadeWindowController mNotificationShadeWindowController;
     private @Mock BroadcastDispatcher mBroadcastDispatcher;
     private @Mock DismissCallbackRegistry mDismissCallbackRegistry;
     private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -77,7 +77,7 @@
         TestableLooper.get(this).runWithLooper(() -> {
             mViewMediator = new KeyguardViewMediator(
                     mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher,
-                    mStatusBarWindowController, () -> mStatusBarKeyguardViewManager,
+                    mNotificationShadeWindowController, () -> mStatusBarKeyguardViewManager,
                     mDismissCallbackRegistry, mUiBgExecutor);
         });
     }
@@ -87,6 +87,6 @@
         mViewMediator.start();
         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
         verify(mUpdateMonitor).setKeyguardGoingAway(false);
-        verify(mStatusBarWindowController, never()).setKeyguardGoingAway(anyBoolean());
+        verify(mNotificationShadeWindowController, never()).setKeyguardGoingAway(anyBoolean());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
index bb9c14b..6d83ac3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
@@ -34,8 +34,8 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import org.junit.Before;
@@ -97,6 +97,6 @@
         viewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
 
         TestableLooper.get(this).processAllMessages();
-        assertFalse(mDependency.hasInstantiatedDependency(StatusBarWindowController.class));
+        assertFalse(mDependency.hasInstantiatedDependency(NotificationShadeWindowController.class));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 3fdbd3e..61e43b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -55,7 +55,7 @@
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
 import com.android.systemui.tests.R;
 
 import java.util.concurrent.CountDownLatch;
@@ -87,7 +87,7 @@
         mContext = context;
         dependency.injectMockDependency(NotificationMediaManager.class);
         dependency.injectMockDependency(BubbleController.class);
-        dependency.injectMockDependency(StatusBarWindowController.class);
+        dependency.injectMockDependency(NotificationShadeWindowController.class);
         dependency.injectMockDependency(SmartReplyController.class);
         StatusBarStateController stateController = mock(StatusBarStateController.class);
         mGroupManager = new NotificationGroupManager(stateController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
index a54f733..a07cfc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
@@ -34,8 +34,8 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
-import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -49,20 +49,22 @@
 
     private ActivityLaunchAnimator mLaunchAnimator;
     private ActivityLaunchAnimator.Callback mCallback = mock(ActivityLaunchAnimator.Callback.class);
-    private StatusBarWindowViewController mStatusBarWindowViewController = mock(
-            StatusBarWindowViewController.class);
-    private StatusBarWindowView mStatusBarWindowView = mock(StatusBarWindowView.class);
+    private NotificationShadeWindowViewController mNotificationShadeWindowViewController = mock(
+            NotificationShadeWindowViewController.class);
+    private NotificationShadeWindowView mNotificationShadeWindowView = mock(
+            NotificationShadeWindowView.class);
     private NotificationListContainer mNotificationContainer
             = mock(NotificationListContainer.class);
     private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class);
 
     @Before
     public void setUp() throws Exception {
-        when(mStatusBarWindowViewController.getView()).thenReturn(mStatusBarWindowView);
-        when(mStatusBarWindowView.getResources()).thenReturn(mContext.getResources());
+        when(mNotificationShadeWindowViewController.getView())
+                .thenReturn(mNotificationShadeWindowView);
+        when(mNotificationShadeWindowView.getResources()).thenReturn(mContext.getResources());
         when(mCallback.areLaunchAnimationsEnabled()).thenReturn(true);
         mLaunchAnimator = new ActivityLaunchAnimator(
-                mStatusBarWindowViewController,
+                mNotificationShadeWindowViewController,
                 mCallback,
                 mock(NotificationPanelViewController.class),
                 mNotificationContainer);
@@ -92,7 +94,7 @@
         RemoteAnimationAdapter launchAnimation = mLaunchAnimator.getLaunchAnimation(mRow,
                 false /* occluded */);
         Assert.assertTrue("No animation generated", launchAnimation != null);
-        executePostsImmediately(mStatusBarWindowView);
+        executePostsImmediately(mNotificationShadeWindowView);
         mLaunchAnimator.setLaunchResult(ActivityManager.START_SUCCESS,
                 true /* wasIntentActivity */);
         verify(mCallback).onExpandAnimationTimedOut();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 61f0b26..9ae477e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -797,7 +797,7 @@
                 null,
                 true);
         verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage(
-                anyString(), anyInt(), any(), eq(CONVERSATION_ID));
+                anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
     }
 
     @Test
@@ -817,7 +817,7 @@
                 null,
                 true);
         verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage(
-                anyString(), anyInt(), any(), eq(CONVERSATION_ID));
+                anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 5907a0a..769b774 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -67,7 +67,7 @@
     @Mock
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock
-    private StatusBarWindowController mStatusBarWindowController;
+    private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock
     private DozeScrimController mDozeScrimController;
     @Mock
@@ -104,9 +104,9 @@
         res.addOverride(com.android.internal.R.integer.config_wakeUpDelayDoze, 0);
         mBiometricUnlockController = new BiometricUnlockController(mContext, mDozeScrimController,
                 mKeyguardViewMediator, mScrimController, mStatusBar, mShadeController,
-                mStatusBarWindowController, mKeyguardStateController, mHandler, mUpdateMonitor,
-                res.getResources(), mKeyguardBypassController, mDozeParameters, mMetricsLogger,
-                mDumpController);
+                mNotificationShadeWindowController, mKeyguardStateController, mHandler,
+                mUpdateMonitor, res.getResources(), mKeyguardBypassController, mDozeParameters,
+                mMetricsLogger, mDumpController);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index d31f175..3c6a698 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -79,12 +79,12 @@
     @Mock private DozeLog mDozeLog;
     @Mock private PulseExpansionHandler mPulseExpansionHandler;
     @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
-    @Mock private StatusBarWindowController mStatusBarWindowController;
+    @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock private PowerManager mPowerManager;
     @Mock private WakefulnessLifecycle mWakefullnessLifecycle;
     @Mock private StatusBar mStatusBar;
     @Mock private NotificationIconAreaController mNotificationIconAreaController;
-    @Mock private StatusBarWindowViewController mStatusBarWindowViewController;
+    @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock private NotificationPanelViewController mNotificationPanel;
     @Mock private View mAmbientIndicationContainer;
@@ -99,12 +99,12 @@
                 mBatteryController, mScrimController, () -> mBiometricUnlockController,
                 mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
                 mKeyguardUpdateMonitor, mVisualStabilityManager, mPulseExpansionHandler,
-                mStatusBarWindowController, mNotificationWakeUpCoordinator,
+                mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
                 mLockscreenLockIconController);
 
         mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController,
-                mStatusBarKeyguardViewManager, mStatusBarWindowViewController, mNotificationPanel,
-                mAmbientIndicationContainer);
+                mStatusBarKeyguardViewManager, mNotificationShadeWindowViewController,
+                mNotificationPanel, mAmbientIndicationContainer);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 7fa6901..50d8bf0b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -57,7 +57,7 @@
     private HeadsUpManagerPhone mHeadsUpManager;
 
     @Mock private NotificationGroupManager mGroupManager;
-    @Mock private View mStatusBarWindowView;
+    @Mock private View mNotificationShadeWindowView;
     @Mock private VisualStabilityManager mVSManager;
     @Mock private StatusBar mBar;
     @Mock private StatusBarStateController mStatusBarStateController;
@@ -65,13 +65,13 @@
     private boolean mLivesPastNormalTime;
 
     private final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
-        TestableHeadsUpManagerPhone(Context context, View statusBarWindowView,
+        TestableHeadsUpManagerPhone(Context context, View notificationShadeWindowView,
                 NotificationGroupManager groupManager, StatusBar bar,
                 VisualStabilityManager vsManager,
                 StatusBarStateController statusBarStateController,
                 KeyguardBypassController keyguardBypassController) {
             super(context, statusBarStateController, keyguardBypassController);
-            setUp(statusBarWindowView, groupManager, bar, vsManager);
+            setUp(notificationShadeWindowView, groupManager, bar, vsManager);
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
         }
@@ -89,9 +89,9 @@
                 .thenReturn(TEST_AUTO_DISMISS_TIME);
         when(mVSManager.isReorderingAllowed()).thenReturn(true);
         mDependency.injectMockDependency(BubbleController.class);
-        mDependency.injectMockDependency(StatusBarWindowController.class);
+        mDependency.injectMockDependency(NotificationShadeWindowController.class);
         mDependency.injectMockDependency(ConfigurationController.class);
-        mHeadsUpManager = new TestableHeadsUpManagerPhone(mContext, mStatusBarWindowView,
+        mHeadsUpManager = new TestableHeadsUpManagerPhone(mContext, mNotificationShadeWindowView,
                 mGroupManager, mBar, mVSManager, mStatusBarStateController, mBypassController);
         super.setUp();
         mHeadsUpManager.mHandler = mTestHandler;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java
similarity index 80%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java
index 147edf6..40d3395 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar.phone;
@@ -25,7 +25,6 @@
 import static org.mockito.Mockito.when;
 
 import android.app.IActivityManager;
-import android.content.res.Resources;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.WindowManager;
@@ -49,11 +48,11 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
-public class StatusBarWindowControllerTest extends SysuiTestCase {
+public class NotificationShadeWindowControllerTest extends SysuiTestCase {
 
     @Mock private WindowManager mWindowManager;
     @Mock private DozeParameters mDozeParameters;
-    @Mock private StatusBarWindowView mStatusBarView;
+    @Mock private NotificationShadeWindowView mStatusBarView;
     @Mock private IActivityManager mActivityManager;
     @Mock private SysuiStatusBarStateController mStatusBarStateController;
     @Mock private ConfigurationController mConfigurationController;
@@ -61,28 +60,28 @@
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock ColorExtractor.GradientColors mGradientColors;
     @Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
-    @Mock private Resources mResources;
 
-    private StatusBarWindowController mStatusBarWindowController;
+    private NotificationShadeWindowController mNotificationShadeWindowController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mDozeParameters.getAlwaysOn()).thenReturn(true);
         when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
-        when(mSuperStatusBarViewFactory.getStatusBarWindowView()).thenReturn(mStatusBarView);
+        when(mSuperStatusBarViewFactory.getNotificationShadeWindowView())
+                .thenReturn(mStatusBarView);
 
-        mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
-                mActivityManager, mDozeParameters, mStatusBarStateController,
+        mNotificationShadeWindowController = new NotificationShadeWindowController(mContext,
+                mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
                 mConfigurationController, mKeyguardBypassController, mColorExtractor,
-                mSuperStatusBarViewFactory, mResources);
+                mSuperStatusBarViewFactory);
 
-        mStatusBarWindowController.attach();
+        mNotificationShadeWindowController.attach();
     }
 
     @Test
     public void testSetDozing_hidesSystemOverlays() {
-        mStatusBarWindowController.setDozing(true);
+        mNotificationShadeWindowController.setDozing(true);
         ArgumentCaptor<WindowManager.LayoutParams> captor =
                 ArgumentCaptor.forClass(WindowManager.LayoutParams.class);
         verify(mWindowManager).updateViewLayout(any(), captor.capture());
@@ -91,7 +90,7 @@
         assertThat(flag).isNotEqualTo(0);
 
         reset(mWindowManager);
-        mStatusBarWindowController.setDozing(false);
+        mNotificationShadeWindowController.setDozing(false);
         verify(mWindowManager).updateViewLayout(any(), captor.capture());
         flag = captor.getValue().privateFlags
                 & WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
@@ -100,7 +99,7 @@
 
     @Test
     public void testOnThemeChanged_doesntCrash() {
-        mStatusBarWindowController.onThemeChanged();
+        mNotificationShadeWindowController.onThemeChanged();
     }
 
     @Test
@@ -110,6 +109,6 @@
 
     @Test
     public void testSetForcePluginOpen_beforeStatusBarInitialization() {
-        mStatusBarWindowController.setForcePluginOpen(true);
+        mNotificationShadeWindowController.setForcePluginOpen(true);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
similarity index 94%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index f9848f3..9853540 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -56,10 +56,10 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-public class StatusBarWindowViewTest extends SysuiTestCase {
+public class NotificationShadeWindowViewTest extends SysuiTestCase {
 
-    private StatusBarWindowView mView;
-    private StatusBarWindowViewController mController;
+    private NotificationShadeWindowView mView;
+    private NotificationShadeWindowViewController mController;
 
     @Mock private NotificationWakeUpCoordinator mCoordinator;
     @Mock private PulseExpansionHandler mPulseExpansionHandler;
@@ -84,15 +84,16 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mView = spy(new StatusBarWindowView(getContext(), null));
+        mView = spy(new NotificationShadeWindowView(getContext(), null));
         when(mView.findViewById(R.id.notification_stack_scroller))
                 .thenReturn(mNotificationStackScrollLayout);
+
         when(mStatusBarStateController.isDozing()).thenReturn(false);
         mDependency.injectTestDependency(ShadeController.class, mShadeController);
 
         when(mDockManager.isDocked()).thenReturn(false);
 
-        mController = new StatusBarWindowViewController(
+        mController = new NotificationShadeWindowViewController(
                 new InjectionInflationController(
                         SystemUIFactory.getInstance().getRootComponent()),
                 mCoordinator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 5b5eaad..675a2df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -104,7 +104,7 @@
                 mock(KeyguardUpdateMonitor.class),
                 mock(NavigationModeController.class),
                 mock(DockManager.class),
-                mock(StatusBarWindowController.class),
+                mock(NotificationShadeWindowController.class),
                 mKeyguardStateController,
                 mock(NotificationMediaManager.class));
         mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
@@ -270,12 +270,12 @@
                 KeyguardUpdateMonitor keyguardUpdateMonitor,
                 NavigationModeController navigationModeController,
                 DockManager dockManager,
-                StatusBarWindowController statusBarWindowController,
+                NotificationShadeWindowController notificationShadeWindowController,
                 KeyguardStateController keyguardStateController,
                 NotificationMediaManager notificationMediaManager) {
             super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
                     configurationController, keyguardUpdateMonitor, navigationModeController,
-                    dockManager, statusBarWindowController, keyguardStateController,
+                    dockManager, notificationShadeWindowController, keyguardStateController,
                     notificationMediaManager);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 782e14c..dd896be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -100,16 +100,17 @@
         mDependency.injectMockDependency(NotificationMediaManager.class);
         mDependency.injectMockDependency(VisualStabilityManager.class);
         mDependency.injectMockDependency(NotificationGutsManager.class);
-        mDependency.injectMockDependency(StatusBarWindowController.class);
+        mDependency.injectMockDependency(NotificationShadeWindowController.class);
         NotificationEntryManager entryManager =
                 mDependency.injectMockDependency(NotificationEntryManager.class);
         when(entryManager.getActiveNotificationsForCurrentUser()).thenReturn(new ArrayList<>());
 
-        StatusBarWindowView statusBarWindowView = mock(StatusBarWindowView.class);
-        when(statusBarWindowView.getResources()).thenReturn(mContext.getResources());
+        NotificationShadeWindowView notificationShadeWindowView =
+                mock(NotificationShadeWindowView.class);
+        when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources());
         mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(mContext,
                 mock(NotificationPanelViewController.class), mock(HeadsUpManagerPhone.class),
-                statusBarWindowView, mock(NotificationListContainerViewGroup.class),
+                notificationShadeWindowView, mock(NotificationListContainerViewGroup.class),
                 mock(DozeScrimController.class), mock(ScrimController.class),
                 mock(ActivityLaunchAnimator.class), mock(DynamicPrivacyController.class),
                 mock(NotificationAlertingManager.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index fee4852..e90e398 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -201,7 +201,7 @@
     @Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
     @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
-    @Mock private StatusBarWindowView mStatusBarWindowView;
+    @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
     @Mock private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private AssistManager mAssistManager;
     @Mock private NotificationGutsManager mNotificationGutsManager;
@@ -224,9 +224,9 @@
     @Mock private BubbleController mBubbleController;
     @Mock private NotificationGroupManager mGroupManager;
     @Mock private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
-    @Mock private StatusBarWindowController mStatusBarWindowController;
+    @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock private NotificationIconAreaController mNotificationIconAreaController;
-    @Mock private StatusBarWindowViewController mStatusBarWindowViewController;
+    @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     @Mock private DozeParameters mDozeParameters;
     @Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
     @Mock private LockscreenWallpaper mLockscreenWallpaper;
@@ -324,11 +324,11 @@
 
         when(mStatusBarComponentBuilderProvider.get()).thenReturn(mStatusBarComponentBuilder);
         when(mStatusBarComponentBuilder.build()).thenReturn(mStatusBarComponent);
-        when(mStatusBarComponent.getStatusBarWindowViewController()).thenReturn(
-                mStatusBarWindowViewController);
+        when(mStatusBarComponent.getNotificationShadeWindowViewController()).thenReturn(
+                mNotificationShadeWindowViewController);
 
         mShadeController = new ShadeControllerImpl(mCommandQueue,
-                mStatusBarStateController, mStatusBarWindowController,
+                mStatusBarStateController, mNotificationShadeWindowController,
                 mStatusBarKeyguardViewManager, mContext.getSystemService(WindowManager.class),
                 () -> mStatusBar, () -> mAssistManager, () -> mBubbleController);
 
@@ -384,7 +384,7 @@
                 () -> mAssistManager,
                 mNotificationListener,
                 configurationController,
-                mStatusBarWindowController,
+                mNotificationShadeWindowController,
                 mLockscreenLockIconController,
                 mDozeParameters,
                 mScrimController,
@@ -417,7 +417,7 @@
                 mNotificationRowBinder,
                 mDismissCallbackRegistry);
 
-        when(mStatusBarWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
+        when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
                 mLockIconContainer);
 
         when(mKeyguardViewMediator.registerStatusBar(any(StatusBar.class), any(ViewGroup.class),
@@ -430,7 +430,7 @@
 
         // TODO: we should be able to call mStatusBar.start() and have all the below values
         // initialized automatically.
-        mStatusBar.mStatusBarWindow = mStatusBarWindowView;
+        mStatusBar.mNotificationShadeWindowView = mNotificationShadeWindowView;
         mStatusBar.mNotificationPanelViewController = mNotificationPanelViewController;
         mStatusBar.mDozeScrimController = mDozeScrimController;
         mStatusBar.mNotificationIconAreaController = mNotificationIconAreaController;
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index e441fb5..cf2b1f06 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -35,7 +35,7 @@
         "framework-tethering",
         "unsupportedappusage",
     ],
-
+    plugins: ["java_api_finder"],
     manifest: "AndroidManifestBase.xml",
 }
 
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 4306cf0b..0491ad7 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -441,7 +441,8 @@
         }
 
         final Boolean setIfaceUp;
-        if (mInterfaceType == TetheringManager.TETHERING_WIFI) {
+        if (mInterfaceType == TetheringManager.TETHERING_WIFI
+                || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
             // The WiFi stack has ownership of the interface up/down state.
             // It is unclear whether the Bluetooth or USB stacks will manage their own
             // state.
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 37e0cc1..8d1e0c9 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -207,6 +207,7 @@
     private Network mTetherUpstream;
     private TetherStatesParcel mTetherStatesParcel;
     private boolean mDataSaverEnabled = false;
+    private String mWifiP2pTetherInterface = null;
 
     public Tethering(TetheringDependencies deps) {
         mLog.mark("Tethering.constructed");
@@ -852,6 +853,11 @@
             }
         }
 
+        private boolean isGroupOwner(WifiP2pGroup group) {
+            return group != null && group.isGroupOwner()
+                    && !TextUtils.isEmpty(group.getInterface());
+        }
+
         private void handleWifiP2pAction(Intent intent) {
             if (mConfig.isWifiP2pLegacyTetheringMode()) return;
 
@@ -864,24 +870,31 @@
                 Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
             }
 
-            if (p2pInfo == null) return;
-            // When a p2p group is disconnected, p2pInfo would be cleared.
-            // group is still valid for detecting whether this device is group owner.
-            if (group == null || !group.isGroupOwner()
-                    || TextUtils.isEmpty(group.getInterface())) return;
-
             synchronized (Tethering.this.mPublicSync) {
-                // Enter below only if this device is Group Owner with a valid interface.
-                if (p2pInfo.groupFormed) {
-                    TetherState tetherState = mTetherStates.get(group.getInterface());
-                    if (tetherState == null
-                            || (tetherState.lastState != IpServer.STATE_TETHERED
-                                && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) {
-                        enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY);
-                    }
-                } else {
-                    disableWifiP2pIpServingLocked(group.getInterface());
+                // if no group is formed, bring it down if needed.
+                if (p2pInfo == null || !p2pInfo.groupFormed) {
+                    disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+                    mWifiP2pTetherInterface = null;
+                    return;
                 }
+
+                // If there is a group but the device is not the owner, bail out.
+                if (!isGroupOwner(group)) return;
+
+                // If already serving from the correct interface, nothing to do.
+                if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
+
+                // If already serving from another interface, turn it down first.
+                if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
+                    mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
+                            + "is different from current interface "
+                            + group.getInterface() + ", re-tether it");
+                    disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+                }
+
+                // Finally bring up serving on the new interface
+                mWifiP2pTetherInterface = group.getInterface();
+                enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
             }
         }
 
@@ -979,7 +992,9 @@
         disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
     }
 
-    private void disableWifiP2pIpServingLocked(String ifname) {
+    private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
+        if (TextUtils.isEmpty(ifname)) return;
+
         disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
     }
 
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 1f50b6b..f29ad78 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -273,7 +273,7 @@
         dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
         InOrder inOrder = inOrder(mCallback, mNetd);
         inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
-                  IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
+                  IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP)));
         inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
         inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
         inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
@@ -547,4 +547,14 @@
         fail("Missing flag: " + match);
         return false;
     }
+
+    private boolean assertNotContainsFlag(String[] flags, String match) {
+        for (String flag : flags) {
+            if (flag.equals(match)) {
+                fail("Unexpected flag: " + match);
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index 5910624..d6afa47 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -493,13 +493,15 @@
 
     private void sendWifiP2pConnectionChanged(
             boolean isGroupFormed, boolean isGroupOwner, String ifname) {
+        WifiP2pGroup group = null;
         WifiP2pInfo p2pInfo = new WifiP2pInfo();
         p2pInfo.groupFormed = isGroupFormed;
-        p2pInfo.isGroupOwner = isGroupOwner;
-
-        WifiP2pGroup group = mock(WifiP2pGroup.class);
-        when(group.isGroupOwner()).thenReturn(isGroupOwner);
-        when(group.getInterface()).thenReturn(ifname);
+        if (isGroupFormed) {
+            p2pInfo.isGroupOwner = isGroupOwner;
+            group = mock(WifiP2pGroup.class);
+            when(group.isGroupOwner()).thenReturn(isGroupOwner);
+            when(group.getInterface()).thenReturn(ifname);
+        }
 
         final Intent intent = mock(Intent.class);
         when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
diff --git a/services/Android.bp b/services/Android.bp
index 5afed6c..a582453 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -6,7 +6,7 @@
 }
 
 filegroup {
-    name: "services-sources",
+    name: "services-all-sources",
     srcs: [
         ":services.core-sources",
         ":services.accessibility-sources",
@@ -29,6 +29,7 @@
         ":services.usage-sources",
         ":services.usb-sources",
         ":services.voiceinteraction-sources",
+        ":service-permission-sources",
     ],
     visibility: ["//visibility:private"],
 }
@@ -110,7 +111,7 @@
 
 droidstubs {
     name: "services-stubs.sources",
-    srcs: [":services-sources"],
+    srcs: [":services-all-sources"],
     installable: false,
     // TODO: remove the --hide options below
     args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES,process=android.annotation.SystemApi.Process.SYSTEM_SERVER\\)" +
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index c3965c4..3e74b7a 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -80,6 +80,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -775,6 +776,16 @@
     }
 
     @Override
+    public @NonNull List<AccessibilityNodeInfo.AccessibilityAction> getSystemActions() {
+        synchronized (mLock) {
+            if (!hasRightsToCurrentUserLocked()) {
+                return Collections.emptyList();
+            }
+        }
+        return mSystemActionPerformer.getSystemActions();
+    }
+
+    @Override
     public boolean isFingerprintGestureDetectionAvailable() {
         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
             return false;
@@ -1252,6 +1263,11 @@
                 gestureEvent).sendToTarget();
     }
 
+    public void notifySystemActionsChangedLocked() {
+        mInvocationHandler.sendEmptyMessage(
+                InvocationHandler.MSG_ON_SYSTEM_ACTIONS_CHANGED);
+    }
+
     public void notifyClearAccessibilityNodeInfoCache() {
         mInvocationHandler.sendEmptyMessage(
                 InvocationHandler.MSG_CLEAR_ACCESSIBILITY_CACHE);
@@ -1350,6 +1366,18 @@
         }
     }
 
+    private void notifySystemActionsChangedInternal() {
+        final IAccessibilityServiceClient listener = getServiceInterfaceSafely();
+        if (listener != null) {
+            try {
+                listener.onSystemActionsChanged();
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error sending system actions change to " + mService,
+                        re);
+            }
+        }
+    }
+
     private void notifyClearAccessibilityCacheInternal() {
         final IAccessibilityServiceClient listener = getServiceInterfaceSafely();
         if (listener != null) {
@@ -1544,6 +1572,7 @@
         private static final int MSG_ON_SOFT_KEYBOARD_STATE_CHANGED = 6;
         private static final int MSG_ON_ACCESSIBILITY_BUTTON_CLICKED = 7;
         private static final int MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 8;
+        private static final int MSG_ON_SYSTEM_ACTIONS_CHANGED = 9;
 
         /** List of magnification callback states, mapping from displayId -> Boolean */
         @GuardedBy("mlock")
@@ -1591,7 +1620,10 @@
                     final boolean available = (message.arg1 != 0);
                     notifyAccessibilityButtonAvailabilityChangedInternal(available);
                 } break;
-
+                case MSG_ON_SYSTEM_ACTIONS_CHANGED: {
+                    notifySystemActionsChangedInternal();
+                    break;
+                }
                 default: {
                     throw new IllegalArgumentException("Unknown message: " + type);
                 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index c733d3b..49582a9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -31,6 +31,7 @@
 
 import com.android.server.LocalServices;
 import com.android.server.accessibility.gestures.TouchExplorer;
+import com.android.server.accessibility.magnification.MagnificationGestureHandler;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.util.ArrayList;
@@ -402,7 +403,7 @@
                 final boolean triggerable = (mEnabledFeatures
                         & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0;
                 MagnificationGestureHandler magnificationGestureHandler =
-                        new MagnificationGestureHandler(displayContext,
+                        new FullScreenMagnificationGestureHandler(displayContext,
                                 mAms.getMagnificationController(),
                                 detectControlGestures, triggerable, displayId);
                 addFirstEventHandler(displayId, magnificationGestureHandler);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index f3a415e..bcaecea 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -137,7 +137,8 @@
         implements AbstractAccessibilityServiceConnection.SystemSupport,
         AccessibilityUserState.ServiceInfoChangeListener,
         AccessibilityWindowManager.AccessibilityEventSender,
-        AccessibilitySecurityPolicy.AccessibilityUserManager {
+        AccessibilitySecurityPolicy.AccessibilityUserManager,
+        SystemActionPerformer.SystemActionsChangedListener {
 
     private static final boolean DEBUG = false;
 
@@ -294,7 +295,8 @@
         mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class);
         mPackageManager = mContext.getPackageManager();
         mSecurityPolicy = new AccessibilitySecurityPolicy(mContext, this);
-        mSystemActionPerformer = new SystemActionPerformer(mContext, mWindowManagerService);
+        mSystemActionPerformer =
+                new SystemActionPerformer(mContext, mWindowManagerService, null, this);
         mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler,
                 mWindowManagerService, this, mSecurityPolicy, this);
         mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler);
@@ -904,6 +906,25 @@
         }
     }
 
+    /**
+     * Called when the system action list is changed.
+     */
+    @Override
+    public void onSystemActionsChanged() {
+        synchronized (mLock) {
+            AccessibilityUserState state = getCurrentUserStateLocked();
+            notifySystemActionsChangedLocked(state);
+        }
+    }
+
+    @VisibleForTesting
+    void notifySystemActionsChangedLocked(AccessibilityUserState userState) {
+        for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
+            AccessibilityServiceConnection service = userState.mBoundServices.get(i);
+            service.notifySystemActionsChangedLocked();
+        }
+    }
+
     @VisibleForTesting
     public boolean notifyKeyEvent(KeyEvent event, int policyFlags) {
         synchronized (mLock) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 8ce92a3..a6041e0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -701,6 +701,7 @@
                 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
                 case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
                 case WindowManager.LayoutParams.TYPE_STATUS_BAR:
+                case WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE:
                 case WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL:
                 case WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL:
                 case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
similarity index 93%
rename from services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
rename to services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
index 06ca054..9e4fd80 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
@@ -53,14 +53,16 @@
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
 import android.view.ViewConfiguration;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.accessibility.gestures.GestureUtils;
+import com.android.server.accessibility.magnification.MagnificationGestureHandler;
 
 import java.util.ArrayDeque;
 import java.util.Queue;
 
 /**
- * This class handles magnification in response to touch events.
+ * This class handles full screen magnification in response to touch events.
  *
  * The behavior is as follows:
  *
@@ -108,14 +110,14 @@
  * 7. The magnification scale will be persisted in settings and in the cloud.
  */
 @SuppressWarnings("WeakerAccess")
-class MagnificationGestureHandler extends BaseEventStreamTransformation {
-    private static final String LOG_TAG = "MagnificationGestureHandler";
+class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler {
+    private static final String LOG_TAG = "FullScreenMagnificationGestureHandler";
 
     private static final boolean DEBUG_ALL = false;
-    private static final boolean DEBUG_STATE_TRANSITIONS = false || DEBUG_ALL;
-    private static final boolean DEBUG_DETECTING = false || DEBUG_ALL;
-    private static final boolean DEBUG_PANNING_SCALING = false || DEBUG_ALL;
-    private static final boolean DEBUG_EVENT_STREAM = false || DEBUG_ALL;
+    private static final boolean DEBUG_STATE_TRANSITIONS = false | DEBUG_ALL;
+    private static final boolean DEBUG_DETECTING = false | DEBUG_ALL;
+    private static final boolean DEBUG_PANNING_SCALING = false | DEBUG_ALL;
+    private static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL;
 
     // The MIN_SCALE is different from MagnificationController.MIN_SCALE due
     // to AccessibilityService.MagnificationController#setScale() has
@@ -167,14 +169,14 @@
      *                           {@code false} if it should ignore such triggers.
      * @param displayId The logical display id.
      */
-    public MagnificationGestureHandler(Context context,
+    FullScreenMagnificationGestureHandler(Context context,
             MagnificationController magnificationController,
             boolean detectTripleTap,
             boolean detectShortcutTrigger,
             int displayId) {
         if (DEBUG_ALL) {
             Log.i(LOG_TAG,
-                    "MagnificationGestureHandler(detectTripleTap = " + detectTripleTap
+                    "FullScreenMagnificationGestureHandler(detectTripleTap = " + detectTripleTap
                             + ", detectShortcutTrigger = " + detectShortcutTrigger + ")");
         }
 
@@ -263,7 +265,8 @@
         clearAndTransitionToStateDetecting();
     }
 
-    void notifyShortcutTriggered() {
+    @Override
+    public void notifyShortcutTriggered() {
         if (mDetectShortcutTrigger) {
             boolean wasMagnifying = mMagnificationController.resetIfNeeded(mDisplayId,
                     /* animate */ true);
@@ -383,10 +386,10 @@
         float mInitialScaleFactor = -1;
         boolean mScaling;
 
-        public PanningScalingState(Context context) {
+        PanningScalingState(Context context) {
             final TypedValue scaleValue = new TypedValue();
             context.getResources().getValue(
-                    com.android.internal.R.dimen.config_screen_magnification_scaling_threshold,
+                    R.dimen.config_screen_magnification_scaling_threshold,
                     scaleValue, false);
             mScalingThreshold = scaleValue.getFloat();
             mScaleGestureDetector = new ScaleGestureDetector(context, this, Handler.getMain());
@@ -407,7 +410,6 @@
             } else if (action == ACTION_UP || action == ACTION_CANCEL) {
 
                 persistScaleAndTransitionTo(mDetectingState);
-
             }
         }
 
@@ -489,10 +491,9 @@
 
         @Override
         public String toString() {
-            return "PanningScalingState{" +
-                    "mInitialScaleFactor=" + mInitialScaleFactor +
-                    ", mScaling=" + mScaling +
-                    '}';
+            return "PanningScalingState{" + "mInitialScaleFactor=" + mInitialScaleFactor
+                    + ", mScaling=" + mScaling
+                    + '}';
         }
     }
 
@@ -544,7 +545,7 @@
                     clear();
                     transitionTo(mDetectingState);
                 }
-                break;
+                    break;
 
                 case ACTION_DOWN:
                 case ACTION_POINTER_UP: {
@@ -561,10 +562,10 @@
 
         @Override
         public String toString() {
-            return "ViewportDraggingState{" +
-                    "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag +
-                    ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion +
-                    '}';
+            return "ViewportDraggingState{"
+                    + "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag
+                    + ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion
+                    + '}';
         }
     }
 
@@ -577,16 +578,17 @@
         @Override
         public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
 
-        	// Ensure that the state at the end of delegation is consistent with the last delegated
+            // Ensures that the state at the end of delegation is consistent with the last delegated
             // UP/DOWN event in queue: still delegating if pointer is down, detecting otherwise
             switch (event.getActionMasked()) {
                 case ACTION_UP:
                 case ACTION_CANCEL: {
                     transitionTo(mDetectingState);
-                } break;
+                }
+                    break;
 
                 case ACTION_DOWN: {
-                	transitionTo(mDelegatingState);
+                    transitionTo(mDelegatingState);
                     mLastDelegatedDownEventTime = event.getDownTime();
                 } break;
             }
@@ -630,11 +632,11 @@
 
         @VisibleForTesting Handler mHandler = new Handler(Looper.getMainLooper(), this);
 
-        public DetectingState(Context context) {
+        DetectingState(Context context) {
             mLongTapMinDelay = ViewConfiguration.getLongPressTimeout();
             mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout()
                     + context.getResources().getInteger(
-                    com.android.internal.R.integer.config_screen_magnification_multi_tap_adjustment);
+                    R.integer.config_screen_magnification_multi_tap_adjustment);
             mSwipeMinDistance = ViewConfiguration.get(context).getScaledTouchSlop();
             mMultiTapMaxDistance = ViewConfiguration.get(context).getScaledDoubleTapSlop();
         }
@@ -913,11 +915,11 @@
 
         @Override
         public String toString() {
-            return "DetectingState{" +
-                    "tapCount()=" + tapCount() +
-                    ", mShortcutTriggered=" + mShortcutTriggered +
-                    ", mDelayedEventQueue=" + MotionEventInfo.toString(mDelayedEventQueue) +
-                    '}';
+            return "DetectingState{"
+                    + "tapCount()=" + tapCount()
+                    + ", mShortcutTriggered=" + mShortcutTriggered
+                    + ", mDelayedEventQueue=" + MotionEventInfo.toString(mDelayedEventQueue)
+                    + '}';
         }
 
         void toggleShortcutTriggered() {
@@ -986,18 +988,18 @@
 
     @Override
     public String toString() {
-        return "MagnificationGesture{" +
-                "mDetectingState=" + mDetectingState +
-                ", mDelegatingState=" + mDelegatingState +
-                ", mMagnifiedInteractionState=" + mPanningScalingState +
-                ", mViewportDraggingState=" + mViewportDraggingState +
-                ", mDetectTripleTap=" + mDetectTripleTap +
-                ", mDetectShortcutTrigger=" + mDetectShortcutTrigger +
-                ", mCurrentState=" + State.nameOf(mCurrentState) +
-                ", mPreviousState=" + State.nameOf(mPreviousState) +
-                ", mMagnificationController=" + mMagnificationController +
-                ", mDisplayId=" + mDisplayId +
-                '}';
+        return "MagnificationGesture{"
+                + "mDetectingState=" + mDetectingState
+                + ", mDelegatingState=" + mDelegatingState
+                + ", mMagnifiedInteractionState=" + mPanningScalingState
+                + ", mViewportDraggingState=" + mViewportDraggingState
+                + ", mDetectTripleTap=" + mDetectTripleTap
+                + ", mDetectShortcutTrigger=" + mDetectShortcutTrigger
+                + ", mCurrentState=" + State.nameOf(mCurrentState)
+                + ", mPreviousState=" + State.nameOf(mPreviousState)
+                + ", mMagnificationController=" + mMagnificationController
+                + ", mDisplayId=" + mDisplayId
+                + '}';
     }
 
     private static final class MotionEventInfo {
@@ -1085,9 +1087,10 @@
      */
     private static class ScreenStateReceiver extends BroadcastReceiver {
         private final Context mContext;
-        private final MagnificationGestureHandler mGestureHandler;
+        private final FullScreenMagnificationGestureHandler mGestureHandler;
 
-        public ScreenStateReceiver(Context context, MagnificationGestureHandler gestureHandler) {
+        ScreenStateReceiver(Context context,
+                FullScreenMagnificationGestureHandler gestureHandler) {
             mContext = context;
             mGestureHandler = gestureHandler;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
new file mode 100644
index 0000000..aa500b5b
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility.magnification;
+
+import com.android.server.accessibility.BaseEventStreamTransformation;
+
+/**
+ * A base class that detects gestures and defines common methods for magnification.
+ */
+public abstract class MagnificationGestureHandler extends BaseEventStreamTransformation {
+
+    /**
+     * Called when the shortcut target is magnification.
+     */
+    public abstract void notifyShortcutTriggered();
+}
diff --git a/services/api/current.txt b/services/api/current.txt
index 18e38b1..8a82e61 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -1,4 +1,49 @@
 // Signature format: 2.0
+package com.android.permission.persistence {
+
+  public interface RuntimePermissionsPersistence {
+    method @NonNull public static com.android.permission.persistence.RuntimePermissionsPersistence createInstance();
+    method public void delete(@NonNull android.os.UserHandle);
+    method @Nullable public com.android.permission.persistence.RuntimePermissionsState read(@NonNull android.os.UserHandle);
+    method public void write(@NonNull com.android.permission.persistence.RuntimePermissionsState, @NonNull android.os.UserHandle);
+  }
+
+  public final class RuntimePermissionsState {
+    ctor public RuntimePermissionsState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>);
+    method @Nullable public String getFingerprint();
+    method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getPackagePermissions();
+    method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getSharedUserPermissions();
+    method public int getVersion();
+    field public static final int NO_VERSION = -1; // 0xffffffff
+  }
+
+  public static class RuntimePermissionsState.PermissionState {
+    ctor public RuntimePermissionsState.PermissionState(@NonNull String, boolean, int);
+    method public int getFlags();
+    method @NonNull public String getName();
+    method public boolean isGranted();
+  }
+
+}
+
+package com.android.role.persistence {
+
+  public interface RolesPersistence {
+    method @NonNull public static com.android.role.persistence.RolesPersistence createInstance();
+    method public void delete(@NonNull android.os.UserHandle);
+    method @Nullable public com.android.role.persistence.RolesState read(@NonNull android.os.UserHandle);
+    method public void write(@NonNull com.android.role.persistence.RolesState, @NonNull android.os.UserHandle);
+  }
+
+  public final class RolesState {
+    ctor public RolesState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>>);
+    method @Nullable public String getPackagesHash();
+    method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getRoles();
+    method public int getVersion();
+  }
+
+}
+
 package com.android.server {
 
   public abstract class SystemService {
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
index 3af15c7..5e6f97e 100644
--- a/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
@@ -20,23 +20,24 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.slice.Slice;
 import android.content.Context;
-import android.os.Handler;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
+import android.service.autofill.InlinePresentation;
 import android.util.Slog;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.autofill.AutofillId;
 import android.view.autofill.IAutoFillManagerClient;
-import android.view.inline.InlinePresentationSpec;
 import android.view.inputmethod.InlineSuggestion;
 import android.view.inputmethod.InlineSuggestionInfo;
-import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InlineSuggestionsResponse;
 
 import com.android.internal.view.inline.IInlineContentCallback;
 import com.android.internal.view.inline.IInlineContentProvider;
+import com.android.server.UiThread;
+import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.autofill.ui.InlineSuggestionUi;
 
 import java.util.ArrayList;
@@ -56,23 +57,59 @@
             int sessionId,
             @NonNull Dataset[] datasets,
             @NonNull AutofillId autofillId,
-            @NonNull InlineSuggestionsRequest request,
-            @NonNull Handler uiHandler,
             @NonNull Context context,
             @NonNull IAutoFillManagerClient client) {
+        if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
+
+        final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
+        final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context);
+        for (Dataset dataset : datasets) {
+            final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
+            if (fieldIndex < 0) {
+                Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
+                return null;
+            }
+            final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(
+                    fieldIndex);
+            if (inlinePresentation == null) {
+                Slog.w(TAG, "InlinePresentation not found in dataset");
+                return null;
+            }
+            InlineSuggestion inlineSuggestion = createAugmentedInlineSuggestion(sessionId, dataset,
+                    inlinePresentation, inlineSuggestionUi, client);
+            inlineSuggestions.add(inlineSuggestion);
+        }
+        return new InlineSuggestionsResponse(inlineSuggestions);
+    }
+
+    /**
+     * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by the
+     * autofill service.
+     */
+    public static InlineSuggestionsResponse createInlineSuggestionsResponse(int requestId,
+            @NonNull Dataset[] datasets,
+            @NonNull AutofillId autofillId,
+            @NonNull Context context,
+            @NonNull AutoFillUI.AutoFillUiCallback client) {
         if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called");
 
         final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
         final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context);
         for (Dataset dataset : datasets) {
-            // TODO(b/146453195): use the spec in the dataset.
-            InlinePresentationSpec spec = request.getPresentationSpecs().get(0);
-            if (spec == null) {
-                Slog.w(TAG, "InlinePresentationSpec is not provided in the response data set");
-                continue;
+            final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
+            if (fieldIndex < 0) {
+                Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
+                return null;
             }
-            InlineSuggestion inlineSuggestion = createAugmentedInlineSuggestion(sessionId, dataset,
-                    autofillId, spec, uiHandler, inlineSuggestionUi, client);
+            final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(
+                    fieldIndex);
+            if (inlinePresentation == null) {
+                Slog.w(TAG, "InlinePresentation not found in dataset");
+                return null;
+            }
+            InlineSuggestion inlineSuggestion = createInlineSuggestion(requestId, dataset,
+                    fieldIndex,
+                    inlinePresentation, inlineSuggestionUi, client);
             inlineSuggestions.add(inlineSuggestion);
         }
         return new InlineSuggestionsResponse(inlineSuggestions);
@@ -80,33 +117,55 @@
 
     private static InlineSuggestion createAugmentedInlineSuggestion(int sessionId,
             @NonNull Dataset dataset,
-            @NonNull AutofillId autofillId,
-            @NonNull InlinePresentationSpec spec,
-            @NonNull Handler uiHandler,
+            @NonNull InlinePresentation inlinePresentation,
             @NonNull InlineSuggestionUi inlineSuggestionUi,
             @NonNull IAutoFillManagerClient client) {
         // TODO(b/146453195): fill in the autofill hint properly.
         final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
-                spec, InlineSuggestionInfo.SOURCE_PLATFORM, new String[]{""});
-        final View.OnClickListener onClickListener = createOnClickListener(sessionId, dataset,
-                client);
+                inlinePresentation.getInlinePresentationSpec(),
+                InlineSuggestionInfo.SOURCE_PLATFORM, new String[]{""});
+        final View.OnClickListener onClickListener = v -> {
+            try {
+                client.autofill(sessionId, dataset.getFieldIds(), dataset.getFieldValues());
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Encounter exception autofilling the values");
+            }
+        };
         final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
-                createInlineContentProvider(autofillId, dataset, uiHandler, inlineSuggestionUi,
+                createInlineContentProvider(inlinePresentation.getSlice(), inlineSuggestionUi,
+                        onClickListener));
+        return inlineSuggestion;
+    }
+
+    private static InlineSuggestion createInlineSuggestion(int requestId,
+            @NonNull Dataset dataset,
+            int fieldIndex,
+            @NonNull InlinePresentation inlinePresentation,
+            @NonNull InlineSuggestionUi inlineSuggestionUi,
+            @NonNull AutoFillUI.AutoFillUiCallback client) {
+        // TODO(b/146453195): fill in the autofill hint properly.
+        final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
+                inlinePresentation.getInlinePresentationSpec(),
+                InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""});
+        final View.OnClickListener onClickListener = v -> {
+            client.fill(requestId, fieldIndex, dataset);
+        };
+        final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
+                createInlineContentProvider(inlinePresentation.getSlice(), inlineSuggestionUi,
                         onClickListener));
         return inlineSuggestion;
     }
 
     private static IInlineContentProvider.Stub createInlineContentProvider(
-            @NonNull AutofillId autofillId, @NonNull Dataset dataset, @NonNull Handler uiHandler,
-            @NonNull InlineSuggestionUi inlineSuggestionUi,
+            @NonNull Slice slice, @NonNull InlineSuggestionUi inlineSuggestionUi,
             @Nullable View.OnClickListener onClickListener) {
         return new IInlineContentProvider.Stub() {
             @Override
             public void provideContent(int width, int height,
                     IInlineContentCallback callback) {
-                uiHandler.post(() -> {
-                    SurfaceControl sc = inlineSuggestionUi.inflate(dataset, autofillId,
-                            width, height, onClickListener);
+                UiThread.getHandler().post(() -> {
+                    SurfaceControl sc = inlineSuggestionUi.inflate(slice, width, height,
+                            onClickListener);
                     try {
                         callback.onContent(sc);
                     } catch (RemoteException e) {
@@ -117,19 +176,6 @@
         };
     }
 
-    private static View.OnClickListener createOnClickListener(int sessionId,
-            @NonNull Dataset dataset,
-            @NonNull IAutoFillManagerClient client) {
-        return v -> {
-            if (sDebug) Slog.d(TAG, "Inline suggestion clicked");
-            try {
-                client.autofill(sessionId, dataset.getFieldIds(), dataset.getFieldValues());
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Encounter exception autofilling the values");
-            }
-        };
-    }
-
     private InlineSuggestionFactory() {
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 2a7357b..5fbdd25 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -161,8 +161,7 @@
                                 @Override
                                 public void onSuccess(@Nullable Dataset[] inlineSuggestionsData) {
                                     maybeHandleInlineSuggestions(sessionId, inlineSuggestionsData,
-                                            focusedId, inlineSuggestionsRequest,
-                                            inlineSuggestionsCallback, client);
+                                            focusedId, inlineSuggestionsCallback, client);
                                     requestAutofill.complete(null);
                                 }
 
@@ -226,19 +225,15 @@
 
     private void maybeHandleInlineSuggestions(int sessionId,
             @Nullable Dataset[] inlineSuggestionsData, @NonNull AutofillId focusedId,
-            @Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
             @Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
             @NonNull IAutoFillManagerClient client) {
-        if (inlineSuggestionsRequest == null
-                || ArrayUtils.isEmpty(inlineSuggestionsData)
-                || inlineSuggestionsCallback == null) {
+        if (ArrayUtils.isEmpty(inlineSuggestionsData) || inlineSuggestionsCallback == null) {
             return;
         }
         try {
             inlineSuggestionsCallback.onInlineSuggestionsResponse(
-                    InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(
-                            sessionId, inlineSuggestionsData, focusedId, inlineSuggestionsRequest,
-                            getJobHandler(), mContext, client));
+                    InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(sessionId,
+                            inlineSuggestionsData, focusedId, mContext, client));
         } catch (RemoteException e) {
             Slog.w(TAG, "Exception sending inline suggestions response back to IME.");
         }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index cdd7510..ee37de5 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -71,7 +71,6 @@
 import android.service.autofill.FillContext;
 import android.service.autofill.FillRequest;
 import android.service.autofill.FillResponse;
-import android.service.autofill.InlinePresentation;
 import android.service.autofill.InternalSanitizer;
 import android.service.autofill.InternalValidator;
 import android.service.autofill.SaveInfo;
@@ -93,9 +92,6 @@
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.autofill.IAutofillWindowPresenter;
-import android.view.inline.InlinePresentationSpec;
-import android.view.inputmethod.InlineSuggestion;
-import android.view.inputmethod.InlineSuggestionInfo;
 import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InlineSuggestionsResponse;
 
@@ -106,8 +102,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.IInlineSuggestionsResponseCallback;
-import com.android.internal.view.inline.IInlineContentCallback;
-import com.android.internal.view.inline.IInlineContentProvider;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.autofill.ui.PendingUi;
 import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -148,6 +142,7 @@
     private final Handler mHandler;
     private final Object mLock;
     private final AutoFillUI mUi;
+    private final Context mContext;
 
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
@@ -773,6 +768,7 @@
         mLock = lock;
         mUi = ui;
         mHandler = handler;
+        mContext = context;
         mRemoteFillService = serviceComponentName == null ? null
                 : new RemoteFillService(context, serviceComponentName, userId, this,
                         bindInstantServiceAllowed);
@@ -2733,35 +2729,11 @@
             return false;
         }
 
-        final int size = datasets.size();
-        final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
-
-        for (int index = 0; index < size; index++) {
-            final Dataset dataset = datasets.get(index);
-            //TODO(b/146453536): Use the proper presentation/spec for currently focused view.
-            final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(0);
-            if (inlinePresentation == null) {
-                if (sDebug) Log.d(TAG, "Missing InlinePresentation on dataset=" + dataset);
-                continue;
-            }
-            final InlinePresentationSpec spec = inlinePresentation.getInlinePresentationSpec();
-            final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
-                    spec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[] { "" });
-
-            inlineSuggestions.add(new InlineSuggestion(inlineSuggestionInfo,
-                    new IInlineContentProvider.Stub() {
-                        @Override
-                        public void provideContent(int width, int height,
-                                IInlineContentCallback callback) throws RemoteException {
-                            getUiForShowing().getSuggestionSurfaceForShowing(dataset, response,
-                                    mCurrentViewId, width, height, callback);
-                        }
-                    }));
-        }
-
+        InlineSuggestionsResponse inlineSuggestionsResponse =
+                InlineSuggestionFactory.createInlineSuggestionsResponse(response.getRequestId(),
+                        datasets.toArray(new Dataset[]{}), mCurrentViewId, mContext, this);
         try  {
-            inlineContentCallback.onInlineSuggestionsResponse(
-                    new InlineSuggestionsResponse(inlineSuggestions));
+            inlineContentCallback.onInlineSuggestionsResponse(inlineSuggestionsResponse);
         } catch (RemoteException e) {
             Log.w(TAG, "onFillReady() remote error calling onInlineSuggestionsResponse()");
             return false;
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 0511bf2..26bb7c3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -37,7 +37,6 @@
 import android.text.TextUtils;
 import android.util.Slog;
 import android.view.KeyEvent;
-import android.view.SurfaceControl;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutofillWindowPresenter;
@@ -45,7 +44,6 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.view.inline.IInlineContentCallback;
 import com.android.server.LocalServices;
 import com.android.server.UiModeManagerInternal;
 import com.android.server.UiThread;
@@ -173,36 +171,6 @@
     }
 
     /**
-     * TODO(b/137800469): Fill in javadoc.
-     * TODO(b/137800469): peoperly manage lifecycle of suggestions surfaces.
-     */
-    public void getSuggestionSurfaceForShowing(@NonNull Dataset dataset,
-            @NonNull FillResponse response, AutofillId autofillId, int width, int height,
-            IInlineContentCallback cb) {
-        if (dataset == null) {
-            Slog.w(TAG, "getSuggestionSurfaceForShowing() called with null dataset");
-        }
-        mHandler.post(() -> {
-            final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(mContext);
-            final SurfaceControl suggestionSurface = inlineSuggestionUi.inflate(dataset,
-                    autofillId, width, height, v -> {
-                        Slog.d(TAG, "Inline suggestion clicked");
-                        hideFillUiUiThread(mCallback, true);
-                        if (mCallback != null) {
-                            final int datasetIndex = response.getDatasets().indexOf(dataset);
-                            mCallback.fill(response.getRequestId(), datasetIndex, dataset);
-                        }
-                    });
-
-            try {
-                cb.onContent(suggestionSurface);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "RemoteException replying onContent(" + suggestionSurface + "): " + e);
-            }
-        });
-    }
-
-    /**
      * Shows the fill UI, removing the previous fill UI if the has changed.
      *
      * @param focusedId the currently focused field
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
index 1e3ee88..2460732 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
@@ -28,17 +28,13 @@
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Icon;
 import android.os.IBinder;
-import android.service.autofill.Dataset;
 import android.util.Log;
-import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillValue;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -69,23 +65,18 @@
      */
     @MainThread
     @Nullable
-    public SurfaceControl inflate(@NonNull Dataset dataset, @NonNull AutofillId autofillId,
-            int width, int height, @Nullable View.OnClickListener onClickListener) {
+    public SurfaceControl inflate(@NonNull Slice slice, int width, int height,
+            @Nullable View.OnClickListener onClickListener) {
         Log.d(TAG, "Inflating the inline suggestion UI");
-        final int index = dataset.getFieldIds().indexOf(autofillId);
-        if (index < 0) {
-            Slog.w(TAG, "inflateInlineSuggestion(): AutofillId=" + autofillId
-                    + " not found in dataset");
-            return null;
-        }
-        final AutofillValue datasetValue = dataset.getFieldValues().get(index);
+
         //TODO(b/137800469): Pass in inputToken from IME.
         final SurfaceControlViewHost wvr = new SurfaceControlViewHost(mContext,
                 mContext.getDisplay(), (IBinder) null);
         final SurfaceControl sc = wvr.getSurfacePackage().getSurfaceControl();
-
-        final ViewGroup suggestionView =
-                (ViewGroup) renderSlice(dataset.getFieldInlinePresentation(index).getSlice());
+        final ViewGroup suggestionView = (ViewGroup) renderSlice(slice);
+        if (onClickListener != null) {
+            suggestionView.setOnClickListener(onClickListener);
+        }
 
         WindowManager.LayoutParams lp =
                 new WindowManager.LayoutParams(width, height,
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index bda0e3b..5e10916 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -47,6 +47,7 @@
 import android.os.SELinux;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -65,14 +66,18 @@
 import com.android.server.backup.remote.RemoteCallable;
 import com.android.server.backup.remote.RemoteResult;
 import com.android.server.backup.transport.TransportClient;
+import com.android.server.backup.transport.TransportNotAvailableException;
 import com.android.server.backup.utils.AppBackupUtils;
 
+import libcore.io.IoUtils;
+
 import java.io.Closeable;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -80,8 +85,10 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -169,10 +176,14 @@
 // TODO: Consider having the caller responsible for some clean-up (like resetting state)
 // TODO: Distinguish between cancel and time-out where possible for logging/monitoring/observing
 public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
+    private static final String TAG = "KVBT";
+
     private static final int THREAD_PRIORITY = Process.THREAD_PRIORITY_BACKGROUND;
     private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
     private static final String BLANK_STATE_FILE_NAME = "blank_state";
     private static final String PM_PACKAGE = UserBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+    private static final String SUCCESS_STATE_SUBDIR = "backing-up";
+    @VisibleForTesting static final String NO_DATA_END_SENTINEL = "@end@";
     @VisibleForTesting public static final String STAGING_FILE_SUFFIX = ".data";
     @VisibleForTesting public static final String NEW_STATE_FILE_SUFFIX = ".new";
 
@@ -336,6 +347,7 @@
 
         mHasDataToBackup = false;
 
+        Set<String> backedUpApps = new HashSet<>();
         int status = BackupTransport.TRANSPORT_OK;
         try {
             startTask();
@@ -347,13 +359,18 @@
                     } else {
                         backupPackage(packageName);
                     }
+                    setSuccessState(packageName, true);
+                    backedUpApps.add(packageName);
                 } catch (AgentException e) {
+                    setSuccessState(packageName, false);
                     if (e.isTransitory()) {
                         // We try again this package in the next backup pass.
                         mBackupManagerService.dataChangedImpl(packageName);
                     }
                 }
             }
+
+            informTransportOfUnchangedApps(backedUpApps);
         } catch (TaskException e) {
             if (e.isStateCompromised()) {
                 mBackupManagerService.resetBackupState(mStateDirectory);
@@ -364,6 +381,185 @@
         finishTask(status);
     }
 
+    /**
+     * Tell the transport about all of the packages which have successfully backed up but
+     * have not informed the framework that they have new data. This allows transports to
+     * differentiate between packages which are not backing data up due to an error and
+     * packages which are not backing up data because nothing has changed.
+     *
+     * The current implementation involves creating a state file when a backup succeeds,
+     * on subsequent runs the existence of the file indicates the backup ran successfully
+     * but there was no data. If a backup fails with an error, or if the package is not
+     * eligible for backup by the transport any more, the status file is removed and the
+     * "no data" message will not be sent to the transport until another successful data
+     * changed backup has succeeded.
+     *
+     * @param appsBackedUp The Set of apps backed up during this run so we can exclude them
+     *                     from the list of successfully backed up apps that we signal to
+     *                     the transport have no data.
+     */
+    private void informTransportOfUnchangedApps(Set<String> appsBackedUp) {
+        String[] succeedingPackages = getSucceedingPackages();
+        if (succeedingPackages == null) {
+            // Nothing is succeeding, so end early.
+            return;
+        }
+
+        int flags = BackupTransport.FLAG_DATA_NOT_CHANGED;
+        if (mUserInitiated) {
+            flags |= BackupTransport.FLAG_USER_INITIATED;
+        }
+
+        boolean noDataPackageEncountered = false;
+        try {
+            IBackupTransport transport =
+                    mTransportClient.connectOrThrow("KVBT.informTransportOfEmptyBackups()");
+
+            for (String packageName : succeedingPackages) {
+                if (appsBackedUp.contains(packageName)) {
+                    Log.v(TAG, "Skipping package which was backed up this time :" + packageName);
+                    // Skip packages we backed up in this run.
+                    continue;
+                }
+
+                PackageInfo packageInfo;
+                try {
+                    packageInfo = mPackageManager.getPackageInfo(packageName, /* flags */ 0);
+                    if (!isEligibleForNoDataCall(packageInfo)) {
+                        // If the package isn't eligible any more we can forget about it and move
+                        // on.
+                        clearStatus(packageName);
+                        continue;
+                    }
+                } catch (PackageManager.NameNotFoundException e) {
+                    // If the package has been uninstalled we can forget about it and move on.
+                    clearStatus(packageName);
+                    continue;
+                }
+
+                sendNoDataChangedTo(transport, packageInfo, flags);
+                noDataPackageEncountered = true;
+            }
+
+            if (noDataPackageEncountered) {
+                // If we've notified the transport of an unchanged package we need to
+                // tell it that it's seen all of the unchanged packages. We do this by
+                // reporting the end sentinel package as unchanged.
+                PackageInfo endSentinal = new PackageInfo();
+                endSentinal.packageName = NO_DATA_END_SENTINEL;
+                sendNoDataChangedTo(transport, endSentinal, flags);
+            }
+        } catch (TransportNotAvailableException | RemoteException e) {
+            Log.e(TAG, "Could not inform transport of all unchanged apps", e);
+        }
+    }
+
+    /** Determine if a package is eligible to be backed up to the transport */
+    private boolean isEligibleForNoDataCall(PackageInfo packageInfo) {
+        return AppBackupUtils.appIsKeyValueOnly(packageInfo)
+                && AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport(mTransportClient,
+                packageInfo.packageName, mPackageManager, mUserId);
+    }
+
+    /** Send the "no data changed" message to a transport for a specific package */
+    private void sendNoDataChangedTo(IBackupTransport transport, PackageInfo packageInfo, int flags)
+            throws RemoteException {
+        ParcelFileDescriptor pfd;
+        try {
+            pfd = ParcelFileDescriptor.open(mBlankStateFile, MODE_READ_ONLY | MODE_CREATE);
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "Unable to find blank state file, aborting unchanged apps signal.");
+            return;
+        }
+        try {
+            int result = transport.performBackup(packageInfo, pfd, flags);
+            if (result == BackupTransport.TRANSPORT_ERROR
+                    || result == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
+                Log.w(
+                        TAG,
+                        "Aborting informing transport of unchanged apps, transport" + " errored");
+                return;
+            }
+
+            transport.finishBackup();
+        } finally {
+            IoUtils.closeQuietly(pfd);
+        }
+    }
+
+    /** Get the list of package names which are marked as having previously succeeded */
+    private String[] getSucceedingPackages() {
+        File stateDirectory = getTopLevelSuccessStateDirectory(/* createIfMissing */ false);
+        if (stateDirectory == null) {
+            // getSuccessStateFileFor logs when we can't use the state area
+            return null;
+        }
+
+        return stateDirectory.list();
+    }
+
+    /** Sets the indicator that a package backup is succeeding */
+    private void setSuccessState(String packageName, boolean success) {
+        File successStateFile = getSuccessStateFileFor(packageName);
+        if (successStateFile == null) {
+            // The error will have been logged by getSuccessStateFileFor().
+            return;
+        }
+
+        if (successStateFile.exists() != success) {
+            // If there's been a change of state
+            if (!success) {
+                // Clear the status if we're now failing
+                clearStatus(packageName, successStateFile);
+                return;
+            }
+
+            // For succeeding packages we want the file
+            try {
+                if (!successStateFile.createNewFile()) {
+                    Log.w(TAG, "Unable to permanently record success for " + packageName);
+                }
+            } catch (IOException e) {
+                Log.w(TAG, "Unable to permanently record success for " + packageName, e);
+            }
+        }
+    }
+
+    /** Clear the status file for a specific package */
+    private void clearStatus(String packageName) {
+        File successStateFile = getSuccessStateFileFor(packageName);
+        if (successStateFile == null) {
+            // The error will have been logged by getSuccessStateFileFor().
+            return;
+        }
+        clearStatus(packageName, successStateFile);
+    }
+
+    /** Clear the status file for a package once we have the File representation */
+    private void clearStatus(String packageName, File successStateFile) {
+        if (successStateFile.exists()) {
+            if (!successStateFile.delete()) {
+                Log.w(TAG, "Unable to remove status file for " + packageName);
+            }
+        }
+    }
+
+    /** Get the backup state file for a package **/
+    private File getSuccessStateFileFor(String packageName) {
+        File stateDirectory = getTopLevelSuccessStateDirectory(/* createIfMissing */ true);
+        return stateDirectory == null ? null : new File(stateDirectory, packageName);
+    }
+
+    /** The top level directory for success state files */
+    private File getTopLevelSuccessStateDirectory(boolean createIfMissing) {
+        File directory = new File(mStateDirectory, SUCCESS_STATE_SUBDIR);
+        if (!directory.exists() && createIfMissing && !directory.mkdirs()) {
+            Log.e(TAG, "Unable to create backing-up state directory");
+            return null;
+        }
+        return directory;
+    }
+
     /** Returns transport status. */
     private int sendDataToTransport(@Nullable PackageInfo packageInfo)
             throws AgentException, TaskException {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index b2fba73..02d4f94 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -90,6 +90,7 @@
     ],
 
     libs: [
+        "services-stubs",
         "services.net",
         "android.hardware.light-V2.0-java",
         "android.hardware.power-V1.0-java",
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
index d84197c..aedafbb 100644
--- a/services/core/java/android/os/UserManagerInternal.java
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -162,7 +162,8 @@
      * createAndManageUser is called by the device owner.
      */
     public abstract UserInfo createUserEvenWhenDisallowed(String name, String userType,
-            int flags, String[] disallowedPackages);
+            int flags, String[] disallowedPackages)
+            throws UserManager.CheckedUserOperationException;
 
     /**
      * Same as {@link UserManager#removeUser(int userId)}, but bypasses the check for
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5e495b9..7ab3453 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5801,6 +5801,19 @@
         return INetd.PERMISSION_NONE;
     }
 
+    private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
+            @NonNull final NetworkCapabilities newNc) {
+        final int oldPermission = getNetworkPermission(nai.networkCapabilities);
+        final int newPermission = getNetworkPermission(newNc);
+        if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
+            try {
+                mNMS.setNetworkPermission(nai.network.netId, newPermission);
+            } catch (RemoteException e) {
+                loge("Exception in setNetworkPermission: " + e);
+            }
+        }
+    }
+
     /**
      * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
      * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
@@ -5848,9 +5861,10 @@
         }
         newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken());
 
-        // TODO : remove this once all factories are updated to send NOT_SUSPENDED
+        // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING
         if (!newNc.hasTransport(TRANSPORT_CELLULAR)) {
             newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+            newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
         }
 
         return newNc;
@@ -5872,21 +5886,11 @@
      * @param nai the network having its capabilities updated.
      * @param nc the new network capabilities.
      */
-    private void updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc) {
+    private void updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai,
+            @NonNull final NetworkCapabilities nc) {
         NetworkCapabilities newNc = mixInCapabilities(nai, nc);
-
         if (Objects.equals(nai.networkCapabilities, newNc)) return;
-
-        final int oldPermission = getNetworkPermission(nai.networkCapabilities);
-        final int newPermission = getNetworkPermission(newNc);
-        if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
-            try {
-                mNMS.setNetworkPermission(nai.network.netId, newPermission);
-            } catch (RemoteException e) {
-                loge("Exception in setNetworkPermission: " + e);
-            }
-        }
-
+        updateNetworkPermissions(nai, newNc);
         final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
 
         updateUids(nai, prevNc, newNc);
@@ -5899,7 +5903,9 @@
             processListenRequests(nai);
             final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
             final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
-            if (prevSuspended != suspended) {
+            final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+            final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+            if (prevSuspended != suspended || prevRoaming != roaming) {
                 // TODO (b/73132094) : remove this call once the few users of onSuspended and
                 // onResumed have been removed.
                 notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED
@@ -6265,6 +6271,30 @@
         }
     }
 
+    // An accumulator class to gather the list of changes that result from a rematch.
+    // TODO : enrich to represent an entire set of changes to apply.
+    private static class NetworkReassignment {
+        static class NetworkBgStatePair {
+            @NonNull final NetworkAgentInfo mNetwork;
+            final boolean mOldBackground;
+            NetworkBgStatePair(@NonNull final NetworkAgentInfo network,
+                    final boolean oldBackground) {
+                mNetwork = network;
+                mOldBackground = oldBackground;
+            }
+        }
+
+        @NonNull private final Set<NetworkBgStatePair> mRematchedNetworks = new ArraySet<>();
+
+        @NonNull Iterable<NetworkBgStatePair> getRematchedNetworks() {
+            return mRematchedNetworks;
+        }
+
+        void addRematchedNetwork(@NonNull final NetworkBgStatePair network) {
+            mRematchedNetworks.add(network);
+        }
+    }
+
     private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork(
             @NonNull final NetworkAgentInfo newNetwork) {
         final int score = newNetwork.getCurrentScore();
@@ -6310,8 +6340,8 @@
     //   needed. A network is needed if it is the best network for
     //   one or more NetworkRequests, or if it is a VPN.
     //
-    // - Tears down newNetwork if it just became validated
-    //   but turns out to be unneeded.
+    // - Writes into the passed reassignment object all changes that should be done for
+    //   rematching this network with all requests, to be applied later.
     //
     // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy,
     // it does not remove NetworkRequests that other Networks could better satisfy.
@@ -6319,15 +6349,22 @@
     // This function should be used when possible instead of {@code rematchAllNetworksAndRequests}
     // as it performs better by a factor of the number of Networks.
     //
+    // TODO : stop writing to the passed reassignment. This is temporarily more useful, but
+    // it's unidiomatic Java and it's hard to read.
+    //
+    // @param changes a currently-building list of changes to write to
     // @param newNetwork is the network to be matched against NetworkRequests.
     // @param now the time the rematch starts, as returned by SystemClock.elapsedRealtime();
-    private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, long now) {
+    private void rematchNetworkAndRequests(@NonNull final NetworkReassignment changes,
+            @NonNull final NetworkAgentInfo newNetwork, final long now) {
         ensureRunningOnConnectivityServiceThread();
         if (!newNetwork.everConnected) return;
         boolean isNewDefault = false;
         NetworkAgentInfo oldDefaultNetwork = null;
 
-        final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork();
+        changes.addRematchedNetwork(new NetworkReassignment.NetworkBgStatePair(newNetwork,
+                newNetwork.isBackgroundNetwork()));
+
         final int score = newNetwork.getCurrentScore();
 
         if (VDBG || DDBG) log("rematching " + newNetwork.name());
@@ -6430,39 +6467,12 @@
         if (newNetwork.getCurrentScore() != score) {
             Slog.wtf(TAG, String.format(
                     "BUG: %s changed score during rematch: %d -> %d",
-                   newNetwork.name(), score, newNetwork.getCurrentScore()));
+                    newNetwork.name(), score, newNetwork.getCurrentScore()));
         }
 
         // Notify requested networks are available after the default net is switched, but
         // before LegacyTypeTracker sends legacy broadcasts
         for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri);
-
-        // Finally, process listen requests and update capabilities if the background state has
-        // changed for this network. For consistency with previous behavior, send onLost callbacks
-        // before onAvailable.
-        processNewlyLostListenRequests(newNetwork);
-
-        // Maybe the network changed background states. Update its capabilities.
-        final boolean backgroundChanged = wasBackgroundNetwork != newNetwork.isBackgroundNetwork();
-        if (backgroundChanged) {
-            final NetworkCapabilities newNc = mixInCapabilities(newNetwork,
-                    newNetwork.networkCapabilities);
-
-            final int oldPermission = getNetworkPermission(newNetwork.networkCapabilities);
-            final int newPermission = getNetworkPermission(newNc);
-            if (oldPermission != newPermission) {
-                try {
-                    mNMS.setNetworkPermission(newNetwork.network.netId, newPermission);
-                } catch (RemoteException e) {
-                    loge("Exception in setNetworkPermission: " + e);
-                }
-            }
-
-            newNetwork.getAndSetNetworkCapabilities(newNc);
-            notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_CAP_CHANGED);
-        }
-
-        processNewlySatisfiedListenRequests(newNetwork);
     }
 
     /**
@@ -6484,12 +6494,24 @@
         // scoring network and then a higher scoring network, which could produce multiple
         // callbacks.
         Arrays.sort(nais);
+        final NetworkReassignment changes = new NetworkReassignment();
         for (final NetworkAgentInfo nai : nais) {
-            rematchNetworkAndRequests(nai, now);
+            rematchNetworkAndRequests(changes, nai, now);
         }
 
         final NetworkAgentInfo newDefaultNetwork = getDefaultNetwork();
 
+        for (final NetworkReassignment.NetworkBgStatePair event : changes.getRematchedNetworks()) {
+            // Process listen requests and update capabilities if the background state has
+            // changed for this network. For consistency with previous behavior, send onLost
+            // callbacks before onAvailable.
+            processNewlyLostListenRequests(event.mNetwork);
+            if (event.mOldBackground != event.mNetwork.isBackgroundNetwork()) {
+                applyBackgroundChangeForRematch(event.mNetwork);
+            }
+            processNewlySatisfiedListenRequests(event.mNetwork);
+        }
+
         for (final NetworkAgentInfo nai : nais) {
             // Rematching may have altered the linger state of some networks, so update all linger
             // timers. updateLingerState reads the state from the network agent and does nothing
@@ -6521,6 +6543,24 @@
         }
     }
 
+    /**
+     * Apply a change in background state resulting from rematching networks with requests.
+     *
+     * During rematch, a network may change background states by starting to satisfy or stopping
+     * to satisfy a foreground request. Listens don't count for this. When a network changes
+     * background states, its capabilities need to be updated and callbacks fired for the
+     * capability change.
+     *
+     * @param nai The network that changed background states
+     */
+    private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
+        final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
+        if (Objects.equals(nai.networkCapabilities, newNc)) return;
+        updateNetworkPermissions(nai, newNc);
+        nai.getAndSetNetworkCapabilities(newNc);
+        notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
+    }
+
     private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
             @Nullable final NetworkAgentInfo oldDefaultNetwork,
             @Nullable final NetworkAgentInfo newDefaultNetwork,
@@ -6615,7 +6655,7 @@
     @NonNull
     private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
         final NetworkInfo newInfo = new NetworkInfo(info);
-        // The suspended bit is managed in NetworkCapabilities.
+        // The suspended and roaming bits are managed in NetworkCapabilities.
         final boolean suspended =
                 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
         if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
@@ -6628,6 +6668,7 @@
             newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
                     info.getExtraInfo());
         }
+        newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
         return newInfo;
     }
 
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index 1ff455ea..c34dd98 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -16,15 +16,273 @@
 
 package com.android.server;
 
-import android.os.IBinder;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.timedetector.NetworkTimeSuggestion;
+import android.app.timedetector.TimeDetector;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.TimestampedValue;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
+
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 
 /**
- * An interface for NetworkTimeUpdateService implementations. Eventually part or all of this service
- * will be subsumed into {@link com.android.server.timedetector.TimeDetectorService}. In the
- * meantime this interface allows Android to use either the old or new implementation.
+ * Monitors the network time. If looking up the network time fails for some reason, it tries a few
+ * times with a short interval and then resets to checking on longer intervals.
+ *
+ * <p>When available, the time is always suggested to the {@link
+ * com.android.server.timedetector.TimeDetectorService} where it may be used to set the device
+ * system clock, depending on user settings and what other signals are available.
  */
-public interface NetworkTimeUpdateService extends IBinder {
+public class NetworkTimeUpdateService extends Binder {
+
+    private static final String TAG = "NetworkTimeUpdateService";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_AUTO_TIME_ENABLED = 1;
+    private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_NETWORK_CHANGED = 3;
+
+    private static final String ACTION_POLL =
+            "com.android.server.NetworkTimeUpdateService.action.POLL";
+
+    private static final int POLL_REQUEST = 0;
+
+    private Network mDefaultNetwork = null;
+
+    private final Context mContext;
+    private final NtpTrustedTime mTime;
+    private final AlarmManager mAlarmManager;
+    private final TimeDetector mTimeDetector;
+    private final ConnectivityManager mCM;
+    private final PendingIntent mPendingPollIntent;
+    private final PowerManager.WakeLock mWakeLock;
+
+    // NTP lookup is done on this thread and handler
+    private Handler mHandler;
+    private AutoTimeSettingObserver mAutoTimeSettingObserver;
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+
+    // Normal polling frequency
+    private final long mPollingIntervalMs;
+    // Try-again polling interval, in case the network request failed
+    private final long mPollingIntervalShorterMs;
+    // Number of times to try again
+    private final int mTryAgainTimesMax;
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    private int mTryAgainCounter;
+
+    public NetworkTimeUpdateService(Context context) {
+        mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
+        mAlarmManager = mContext.getSystemService(AlarmManager.class);
+        mTimeDetector = mContext.getSystemService(TimeDetector.class);
+        mCM = mContext.getSystemService(ConnectivityManager.class);
+
+        Intent pollIntent = new Intent(ACTION_POLL, null);
+        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
+
+        mPollingIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingInterval);
+        mPollingIntervalShorterMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+        mTryAgainTimesMax = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpRetry);
+
+        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
 
     /** Initialize the receivers and initiate the first NTP request */
-    void systemRunning();
+    public void systemRunning() {
+        registerForAlarms();
+
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mHandler = new MyHandler(thread.getLooper());
+        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
+        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
+
+        mAutoTimeSettingObserver = new AutoTimeSettingObserver(mContext, mHandler,
+                EVENT_AUTO_TIME_ENABLED);
+        mAutoTimeSettingObserver.observe();
+    }
+
+    private void registerForAlarms() {
+        mContext.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
+                    }
+                }, new IntentFilter(ACTION_POLL));
+    }
+
+    private void onPollNetworkTime(int event) {
+        // If we don't have any default network, don't bother.
+        if (mDefaultNetwork == null) return;
+        mWakeLock.acquire();
+        try {
+            onPollNetworkTimeUnderWakeLock(event);
+        } finally {
+            mWakeLock.release();
+        }
+    }
+
+    private void onPollNetworkTimeUnderWakeLock(int event) {
+        // Force an NTP fix when outdated
+        NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult();
+        if (cachedNtpResult == null || cachedNtpResult.getAgeMillis() >= mPollingIntervalMs) {
+            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
+            mTime.forceRefresh();
+            cachedNtpResult = mTime.getCachedTimeResult();
+        }
+
+        if (cachedNtpResult != null && cachedNtpResult.getAgeMillis() < mPollingIntervalMs) {
+            // Obtained fresh fix; schedule next normal update
+            resetAlarm(mPollingIntervalMs);
+
+            // Suggest the time to the time detector. It may choose use it to set the system clock.
+            TimestampedValue<Long> timeSignal = new TimestampedValue<>(
+                    cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis());
+            NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
+            timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateService. event=" + event);
+            mTimeDetector.suggestNetworkTime(timeSuggestion);
+        } else {
+            // No fresh fix; schedule retry
+            mTryAgainCounter++;
+            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+                resetAlarm(mPollingIntervalShorterMs);
+            } else {
+                // Try much later
+                mTryAgainCounter = 0;
+                resetAlarm(mPollingIntervalMs);
+            }
+        }
+    }
+
+    /**
+     * Cancel old alarm and starts a new one for the specified interval.
+     *
+     * @param interval when to trigger the alarm, starting from now.
+     */
+    private void resetAlarm(long interval) {
+        mAlarmManager.cancel(mPendingPollIntent);
+        long now = SystemClock.elapsedRealtime();
+        long next = now + interval;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
+    }
+
+    /** Handler to do the network accesses on */
+    private class MyHandler extends Handler {
+
+        MyHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_TIME_ENABLED:
+                case EVENT_POLL_NETWORK_TIME:
+                case EVENT_NETWORK_CHANGED:
+                    onPollNetworkTime(msg.what);
+                    break;
+            }
+        }
+    }
+
+    private class NetworkTimeUpdateCallback extends NetworkCallback {
+        @Override
+        public void onAvailable(Network network) {
+            Log.d(TAG, String.format("New default network %s; checking time.", network));
+            mDefaultNetwork = network;
+            // Running on mHandler so invoke directly.
+            onPollNetworkTime(EVENT_NETWORK_CHANGED);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
+        }
+    }
+
+    /**
+     * Observer to watch for changes to the AUTO_TIME setting. It only triggers when the setting
+     * is enabled.
+     */
+    private static class AutoTimeSettingObserver extends ContentObserver {
+
+        private final Context mContext;
+        private final int mMsg;
+        private final Handler mHandler;
+
+        AutoTimeSettingObserver(Context context, Handler handler, int msg) {
+            super(handler);
+            mContext = context;
+            mHandler = handler;
+            mMsg = msg;
+        }
+
+        void observe() {
+            ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (isAutomaticTimeEnabled()) {
+                mHandler.obtainMessage(mMsg).sendToTarget();
+            }
+        }
+
+        /**
+         * Checks if the user prefers to automatically set the time.
+         */
+        private boolean isAutomaticTimeEnabled() {
+            ContentResolver resolver = mContext.getContentResolver();
+            return Settings.Global.getInt(resolver, Settings.Global.AUTO_TIME, 0) != 0;
+        }
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        pw.print("PollingIntervalMs: ");
+        TimeUtils.formatDuration(mPollingIntervalMs, pw);
+        pw.print("\nPollingIntervalShorterMs: ");
+        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+        NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult();
+        pw.println("NTP cache result: " + ntpResult);
+        if (ntpResult != null) {
+            pw.println("NTP result age: " + ntpResult.getAgeMillis());
+        }
+        pw.println();
+    }
 }
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java
deleted file mode 100644
index 7894788..0000000
--- a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.TimeDetector;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.os.TimestampedValue;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
-
-import com.android.internal.util.DumpUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Monitors the network time. If looking up the network time fails for some reason, it tries a few
- * times with a short interval and then resets to checking on longer intervals.
- *
- * <p>When available, the time is always suggested to the {@link
- * com.android.server.timedetector.TimeDetectorService} where it may be used to set the device
- * system clock, depending on user settings and what other signals are available.
- */
-public class NetworkTimeUpdateServiceImpl extends Binder implements NetworkTimeUpdateService {
-
-    private static final String TAG = "NetworkTimeUpdateService";
-    private static final boolean DBG = false;
-
-    private static final int EVENT_AUTO_TIME_ENABLED = 1;
-    private static final int EVENT_POLL_NETWORK_TIME = 2;
-    private static final int EVENT_NETWORK_CHANGED = 3;
-
-    private static final String ACTION_POLL =
-            "com.android.server.NetworkTimeUpdateService.action.POLL";
-
-    private static final int POLL_REQUEST = 0;
-
-    private Network mDefaultNetwork = null;
-
-    private final Context mContext;
-    private final NtpTrustedTime mTime;
-    private final AlarmManager mAlarmManager;
-    private final TimeDetector mTimeDetector;
-    private final ConnectivityManager mCM;
-    private final PendingIntent mPendingPollIntent;
-    private final PowerManager.WakeLock mWakeLock;
-
-    // NTP lookup is done on this thread and handler
-    private Handler mHandler;
-    private AutoTimeSettingObserver mAutoTimeSettingObserver;
-    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-
-    // Normal polling frequency
-    private final long mPollingIntervalMs;
-    // Try-again polling interval, in case the network request failed
-    private final long mPollingIntervalShorterMs;
-    // Number of times to try again
-    private final int mTryAgainTimesMax;
-    // Keeps track of how many quick attempts were made to fetch NTP time.
-    // During bootup, the network may not have been up yet, or it's taking time for the
-    // connection to happen.
-    private int mTryAgainCounter;
-
-    public NetworkTimeUpdateServiceImpl(Context context) {
-        mContext = context;
-        mTime = NtpTrustedTime.getInstance(context);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mTimeDetector = mContext.getSystemService(TimeDetector.class);
-        mCM = mContext.getSystemService(ConnectivityManager.class);
-
-        Intent pollIntent = new Intent(ACTION_POLL, null);
-        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
-
-        mPollingIntervalMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingInterval);
-        mPollingIntervalShorterMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
-        mTryAgainTimesMax = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpRetry);
-
-        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, TAG);
-    }
-
-    @Override
-    public void systemRunning() {
-        registerForAlarms();
-
-        HandlerThread thread = new HandlerThread(TAG);
-        thread.start();
-        mHandler = new MyHandler(thread.getLooper());
-        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
-        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
-
-        mAutoTimeSettingObserver = new AutoTimeSettingObserver(mContext, mHandler,
-                EVENT_AUTO_TIME_ENABLED);
-        mAutoTimeSettingObserver.observe();
-    }
-
-    private void registerForAlarms() {
-        mContext.registerReceiver(
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
-                }
-            }, new IntentFilter(ACTION_POLL));
-    }
-
-    private void onPollNetworkTime(int event) {
-        // If we don't have any default network, don't bother.
-        if (mDefaultNetwork == null) return;
-        mWakeLock.acquire();
-        try {
-            onPollNetworkTimeUnderWakeLock(event);
-        } finally {
-            mWakeLock.release();
-        }
-    }
-
-    private void onPollNetworkTimeUnderWakeLock(int event) {
-        // Force an NTP fix when outdated
-        NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult();
-        if (cachedNtpResult == null || cachedNtpResult.getAgeMillis() >= mPollingIntervalMs) {
-            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            mTime.forceRefresh();
-            cachedNtpResult = mTime.getCachedTimeResult();
-        }
-
-        if (cachedNtpResult != null && cachedNtpResult.getAgeMillis() < mPollingIntervalMs) {
-            // Obtained fresh fix; schedule next normal update
-            resetAlarm(mPollingIntervalMs);
-
-            // Suggest the time to the time detector. It may choose use it to set the system clock.
-            TimestampedValue<Long> timeSignal = new TimestampedValue<>(
-                    cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis());
-            NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
-            timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateServiceImpl. event=" + event);
-            mTimeDetector.suggestNetworkTime(timeSuggestion);
-        } else {
-            // No fresh fix; schedule retry
-            mTryAgainCounter++;
-            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
-                resetAlarm(mPollingIntervalShorterMs);
-            } else {
-                // Try much later
-                mTryAgainCounter = 0;
-                resetAlarm(mPollingIntervalMs);
-            }
-        }
-    }
-
-    /**
-     * Cancel old alarm and starts a new one for the specified interval.
-     *
-     * @param interval when to trigger the alarm, starting from now.
-     */
-    private void resetAlarm(long interval) {
-        mAlarmManager.cancel(mPendingPollIntent);
-        long now = SystemClock.elapsedRealtime();
-        long next = now + interval;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
-    }
-
-    /** Handler to do the network accesses on */
-    private class MyHandler extends Handler {
-
-        public MyHandler(Looper l) {
-            super(l);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_AUTO_TIME_ENABLED:
-                case EVENT_POLL_NETWORK_TIME:
-                case EVENT_NETWORK_CHANGED:
-                    onPollNetworkTime(msg.what);
-                    break;
-            }
-        }
-    }
-
-    private class NetworkTimeUpdateCallback extends NetworkCallback {
-        @Override
-        public void onAvailable(Network network) {
-            Log.d(TAG, String.format("New default network %s; checking time.", network));
-            mDefaultNetwork = network;
-            // Running on mHandler so invoke directly.
-            onPollNetworkTime(EVENT_NETWORK_CHANGED);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
-        }
-    }
-
-    /**
-     * Observer to watch for changes to the AUTO_TIME setting. It only triggers when the setting
-     * is enabled.
-     */
-    private static class AutoTimeSettingObserver extends ContentObserver {
-
-        private final Context mContext;
-        private final int mMsg;
-        private final Handler mHandler;
-
-        AutoTimeSettingObserver(Context context, Handler handler, int msg) {
-            super(handler);
-            mContext = context;
-            mHandler = handler;
-            mMsg = msg;
-        }
-
-        void observe() {
-            ContentResolver resolver = mContext.getContentResolver();
-            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
-                    false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            if (isAutomaticTimeEnabled()) {
-                mHandler.obtainMessage(mMsg).sendToTarget();
-            }
-        }
-
-        /**
-         * Checks if the user prefers to automatically set the time.
-         */
-        private boolean isAutomaticTimeEnabled() {
-            ContentResolver resolver = mContext.getContentResolver();
-            return Settings.Global.getInt(resolver, Settings.Global.AUTO_TIME, 0) != 0;
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult();
-        pw.println("NTP cache result: " + ntpResult);
-        if (ntpResult != null) {
-            pw.println("NTP result age: " + ntpResult.getAgeMillis());
-        }
-        pw.println();
-    }
-}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index bcc3bdb..32830ae 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -37,6 +37,8 @@
 import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIED;
 import static android.os.storage.OnObbStateChangeListener.MOUNTED;
 import static android.os.storage.OnObbStateChangeListener.UNMOUNTED;
+import static android.os.storage.StorageManager.PROP_FUSE;
+import static android.os.storage.StorageManager.PROP_SETTINGS_FUSE;
 
 import static com.android.internal.util.XmlUtils.readIntAttribute;
 import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -1617,7 +1619,10 @@
         SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT, Boolean.toString(
                 SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, true)));
 
-        mIsFuseEnabled = SystemProperties.getBoolean(StorageManager.PROP_FUSE, false);
+        // If there is no value in the property yet (first boot after data wipe), this value may be
+        // incorrect until #updateFusePropFromSettings where we set the correct value and reboot if
+        // different
+        mIsFuseEnabled = SystemProperties.getBoolean(PROP_FUSE, false);
         mContext = context;
         mResolver = mContext.getContentResolver();
         mCallbacks = new Callbacks(FgThread.get().getLooper());
@@ -1680,25 +1685,24 @@
      *  and updates PROP_FUSE (reboots if changed).
      */
     private void updateFusePropFromSettings() {
-        String settingsFuseFlag = SystemProperties.get(StorageManager.PROP_SETTINGS_FUSE);
-        Slog.d(TAG, "The value of Settings Fuse Flag is "
-                + (settingsFuseFlag == null || settingsFuseFlag.isEmpty()
-                ? "null" : settingsFuseFlag));
-        // Set default value of PROP_SETTINGS_FUSE and PROP_FUSE if it
-        // is unset (neither true nor false, this happens only on the first boot
-        // after wiping data partition).
-        if (settingsFuseFlag == null || settingsFuseFlag.isEmpty()) {
-            SystemProperties.set(StorageManager.PROP_SETTINGS_FUSE, "false");
-            SystemProperties.set(StorageManager.PROP_FUSE, "false");
+        boolean defaultFuseFlag = false;
+        boolean settingsFuseFlag = SystemProperties.getBoolean(PROP_SETTINGS_FUSE, defaultFuseFlag);
+        Slog.d(TAG, "FUSE flags. Settings: " + settingsFuseFlag + ". Default: " + defaultFuseFlag);
+
+        if (TextUtils.isEmpty(SystemProperties.get(PROP_SETTINGS_FUSE))) {
+            // Set default value of PROP_SETTINGS_FUSE and PROP_FUSE if it
+            // is unset (neither true nor false).
+            // This happens only on the first boot after wiping data partition
+            SystemProperties.set(PROP_SETTINGS_FUSE, Boolean.toString(defaultFuseFlag));
+            SystemProperties.set(PROP_FUSE, Boolean.toString(defaultFuseFlag));
             return;
         }
 
-        if (!SystemProperties.get(StorageManager.PROP_FUSE).equals(settingsFuseFlag)) {
-            Slog.d(TAG, "Set persist.sys.fuse to " + settingsFuseFlag);
-            SystemProperties.set(StorageManager.PROP_FUSE, settingsFuseFlag);
+        if (mIsFuseEnabled != settingsFuseFlag) {
+            Slog.i(TAG, "Toggling persist.sys.fuse to " + settingsFuseFlag);
+            SystemProperties.set(PROP_FUSE, Boolean.toString(settingsFuseFlag));
             // Perform hard reboot to kick policy into place
-            mContext.getSystemService(PowerManager.class).reboot("Reboot device for FUSE system"
-                    + "property change to take effect");
+            mContext.getSystemService(PowerManager.class).reboot("fuse_prop");
         }
     }
 
@@ -1997,10 +2001,11 @@
                         } catch (ExternalStorageServiceException e) {
                             Slog.e(TAG, "Failed to mount volume " + vol, e);
 
-                            Slog.i(TAG, "Scheduling reset in one minute");
+                            int nextResetSeconds = REMOTE_TIMEOUT_SECONDS * 2;
+                            Slog.i(TAG, "Scheduling reset in " + nextResetSeconds + "s");
                             mHandler.removeMessages(H_RESET);
                             mHandler.sendMessageDelayed(mHandler.obtainMessage(H_RESET),
-                                    TimeUnit.SECONDS.toMillis(REMOTE_TIMEOUT_SECONDS * 2));
+                                    TimeUnit.SECONDS.toMillis(nextResetSeconds));
                             return false;
                         } finally {
                             try {
@@ -2989,6 +2994,24 @@
     }
 
     /*
+     * Clear disk encryption key bound to the associated token / secret pair. Removing the user
+     * binding of the Disk encryption key is done in two phases: first, this call will retrieve
+     * the disk encryption key using the provided token / secret pair and store it by
+     * encrypting it with a keymaster key not bound to the user, then fixateNewestUserKeyAuth
+     * is called to delete all other bindings of the disk encryption key.
+     */
+    @Override
+    public void clearUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+
+        try {
+            mVold.clearUserKeyAuth(userId, serialNumber, encodeBytes(token), encodeBytes(secret));
+        } catch (Exception e) {
+            Slog.wtf(TAG, e);
+        }
+    }
+
+    /*
      * Delete all disk encryption token/secret pairs except the most recently added one
      */
     @Override
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4f03a8e..7324d97 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2413,43 +2413,12 @@
         Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         intent.putExtra(PHONE_CONSTANTS_STATE_KEY, dataStateToString(state));
         intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn);
-        intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, getApnTypesStringFromBitmask(apnType));
+        intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY,
+                ApnSetting.getApnTypesStringFromBitmask(apnType));
         intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
-    private static final Map<Integer, String> APN_TYPE_INT_MAP;
-    static {
-        APN_TYPE_INT_MAP = new android.util.ArrayMap<Integer, String>();
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_DEFAULT, "default");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_MMS, "mms");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_SUPL, "supl");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_DUN, "dun");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_HIPRI, "hipri");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_FOTA, "fota");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_IMS, "ims");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_CBS, "cbs");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_IA, "ia");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_EMERGENCY, "emergency");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_MCX, "mcx");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_XCAP, "xcap");
-    }
-
-    /**
-     * Copy of ApnSetting#getApnTypesStringFromBitmask for legacy broadcast.
-     * @param apnTypeBitmask bitmask of APN types.
-     * @return comma delimited list of APN types.
-     */
-    private static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
-        List<String> types = new ArrayList<>();
-        for (Integer type : APN_TYPE_INT_MAP.keySet()) {
-            if ((apnTypeBitmask & type) == type) {
-                types.add(APN_TYPE_INT_MAP.get(type));
-            }
-        }
-        return android.text.TextUtils.join(",", types);
-    }
-
     private void enforceNotifyPermissionOrCarrierPrivilege(String method) {
         if (checkNotifyPermission()) {
             return;
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index ed3bab9..35a9802 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -218,7 +218,7 @@
             // Has to be in TestNetworkAgent to ensure all teardown codepaths properly clean up
             // resources, even for binder death or unwanted calls.
             synchronized (mTestNetworkTracker) {
-                mTestNetworkTracker.remove(network.netId);
+                mTestNetworkTracker.remove(getNetwork().netId);
             }
         }
     }
@@ -337,7 +337,7 @@
                                             callingUid,
                                             binder);
 
-                            mTestNetworkTracker.put(agent.network.netId, agent);
+                            mTestNetworkTracker.put(agent.getNetwork().netId, agent);
                         }
                     } catch (SocketException e) {
                         throw new UncheckedIOException(e);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e2a036a..3ffa5de 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -36,6 +36,7 @@
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.ApplicationExitInfo;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
 import android.app.Notification;
@@ -2730,7 +2731,7 @@
             created = true;
         } catch (DeadObjectException e) {
             Slog.w(TAG, "Application dead when creating service " + r);
-            mAm.appDiedLocked(app);
+            mAm.appDiedLocked(app, "Died when creating service");
             throw e;
         } finally {
             if (!created) {
@@ -3649,7 +3650,8 @@
                             && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID
                             && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
                         proc.kill("bound to service " + sr.shortInstanceName
-                                + " in dying proc " + (app != null ? app.processName : "??"), true);
+                                + " in dying proc " + (app != null ? app.processName : "??"),
+                                ApplicationExitInfo.REASON_OTHER, true);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 9085d18..fc4bad7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -30,10 +30,14 @@
 import android.provider.DeviceConfig.Properties;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
 import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Settings constants that can modify the activity manager's behavior.
@@ -65,6 +69,10 @@
             = "service_usage_interaction_time";
     private static final String KEY_USAGE_STATS_INTERACTION_INTERVAL
             = "usage_stats_interaction_interval";
+    private static final String KEY_IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES =
+            "imperceptible_kill_exempt_packages";
+    private static final String KEY_IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES =
+            "imperceptible_kill_exempt_proc_states";
     static final String KEY_SERVICE_RESTART_DURATION = "service_restart_duration";
     static final String KEY_SERVICE_RESET_RUN_DURATION = "service_reset_run_duration";
     static final String KEY_SERVICE_RESTART_DURATION_FACTOR = "service_restart_duration_factor";
@@ -282,6 +290,19 @@
     // memory trimming.
     public int CUR_TRIM_CACHED_PROCESSES;
 
+    /**
+     * Packages that can't be killed even if it's requested to be killed on imperceptible.
+     */
+    public ArraySet<String> IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES = new ArraySet<String>();
+
+    /**
+     * Proc State that can't be killed even if it's requested to be killed on imperceptible.
+     */
+    public ArraySet<Integer> IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES = new ArraySet<Integer>();
+
+    private List<String> mDefaultImperceptibleKillExemptPackages;
+    private List<Integer> mDefaultImperceptibleKillExemptProcStates;
+
     @SuppressWarnings("unused")
     private static final int OOMADJ_UPDATE_POLICY_SLOW = 0;
     private static final int OOMADJ_UPDATE_POLICY_QUICK = 1;
@@ -332,6 +353,10 @@
                             case KEY_OOMADJ_UPDATE_POLICY:
                                 updateOomAdjUpdatePolicy();
                                 break;
+                            case KEY_IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES:
+                            case KEY_IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES:
+                                updateImperceptibleKillExemptions();
+                                break;
                             default:
                                 break;
                         }
@@ -350,6 +375,13 @@
                 MIN_AUTOMATIC_HEAP_DUMP_PSS_THRESHOLD_BYTES,
                 context.getResources().getInteger(
                         com.android.internal.R.integer.config_debugSystemServerPssThresholdBytes));
+        mDefaultImperceptibleKillExemptPackages = Arrays.asList(
+                context.getResources().getStringArray(
+                com.android.internal.R.array.config_defaultImperceptibleKillingExemptionPkgs));
+        mDefaultImperceptibleKillExemptProcStates = Arrays.stream(
+                context.getResources().getIntArray(
+                com.android.internal.R.array.config_defaultImperceptibleKillingExemptionProcStates))
+                .boxed().collect(Collectors.toList());
     }
 
     public void start(ContentResolver resolver) {
@@ -371,6 +403,7 @@
         updateActivityStartsLoggingEnabled();
         updateBackgroundActivityStarts();
         updateOomAdjUpdatePolicy();
+        updateImperceptibleKillExemptions();
     }
 
     public void setOverrideMaxCachedProcesses(int value) {
@@ -497,6 +530,29 @@
                 == OOMADJ_UPDATE_POLICY_QUICK;
     }
 
+    private void updateImperceptibleKillExemptions() {
+        IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear();
+        IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages);
+        String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES, null);
+        if (!TextUtils.isEmpty(val)) {
+            IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(Arrays.asList(val.split(",")));
+        }
+
+        IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.clear();
+        IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.addAll(mDefaultImperceptibleKillExemptProcStates);
+        val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES, null);
+        if (!TextUtils.isEmpty(val)) {
+            Arrays.asList(val.split(",")).stream().forEach((v) -> {
+                try {
+                    IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.add(Integer.parseInt(v));
+                } catch (NumberFormatException e) {
+                }
+            });
+        }
+    }
+
     private void updateEnableAutomaticSystemServerHeapDumps() {
         if (!mSystemServerAutomaticHeapDumpEnabled) {
             Slog.wtf(TAG,
@@ -603,6 +659,10 @@
         pw.println(MEMORY_INFO_THROTTLE_TIME);
         pw.print("  "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("=");
         pw.println(TOP_TO_FGS_GRACE_DURATION);
+        pw.print("  "); pw.print(KEY_IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES); pw.print("=");
+        pw.println(Arrays.toString(IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.toArray()));
+        pw.print("  "); pw.print(KEY_IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES); pw.print("=");
+        pw.println(Arrays.toString(IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.toArray()));
 
         pw.println();
         if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 883e7c6..d9fbc85 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -155,6 +155,7 @@
 import android.app.AppOpsManager;
 import android.app.AppOpsManagerInternal.CheckOpsDelegate;
 import android.app.ApplicationErrorReport;
+import android.app.ApplicationExitInfo;
 import android.app.ApplicationThreadConstants;
 import android.app.BroadcastOptions;
 import android.app.ContentProviderHolder;
@@ -362,6 +363,7 @@
 import com.android.server.wm.ActivityServiceConnectionsHolder;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.ActivityTaskManagerService;
+import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerService;
 import com.android.server.wm.WindowProcessController;
 
@@ -684,7 +686,7 @@
     /**
      * Process management.
      */
-    final ProcessList mProcessList = new ProcessList();
+    final ProcessList mProcessList;
 
     /**
      * Tracking long-term execution of processes to look for abuse and other
@@ -1504,6 +1506,7 @@
 
     @VisibleForTesting
     public WindowManagerService mWindowManager;
+    WindowManagerInternal mWmInternal;
     @VisibleForTesting
     public ActivityTaskManagerService mActivityTaskManager;
     @VisibleForTesting
@@ -1534,7 +1537,7 @@
                 TAG, "Death received in " + this
                 + " for thread " + mAppThread.asBinder());
             synchronized(ActivityManagerService.this) {
-                appDiedLocked(mApp, mPid, mAppThread, true);
+                appDiedLocked(mApp, mPid, mAppThread, true, null);
             }
         }
     }
@@ -2084,6 +2087,7 @@
     public void setWindowManager(WindowManagerService wm) {
         synchronized (this) {
             mWindowManager = wm;
+            mWmInternal = LocalServices.getService(WindowManagerInternal.class);
             mActivityTaskManager.setWindowManager(wm);
         }
     }
@@ -2382,6 +2386,7 @@
                 ? new ActivityManagerConstants(mContext, this, mHandler) : null;
         final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
         mPlatformCompat = null;
+        mProcessList = injector.getProcessList(this);
         mProcessList.init(this, activeUids, mPlatformCompat);
         mLowMemDetector = null;
         mOomAdjuster = hasHandlerThread
@@ -2436,6 +2441,7 @@
         final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
         mPlatformCompat = (PlatformCompat) ServiceManager.getService(
                 Context.PLATFORM_COMPAT_SERVICE);
+        mProcessList = mInjector.getProcessList(this);
         mProcessList.init(this, activeUids, mPlatformCompat);
         mLowMemDetector = new LowMemDetector(this);
         mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
@@ -3680,13 +3686,13 @@
     }
 
     @GuardedBy("this")
-    final void appDiedLocked(ProcessRecord app) {
-       appDiedLocked(app, app.pid, app.thread, false);
+    final void appDiedLocked(ProcessRecord app, String reason) {
+        appDiedLocked(app, app.pid, app.thread, false, reason);
     }
 
     @GuardedBy("this")
     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
-            boolean fromBinderDied) {
+            boolean fromBinderDied, String reason) {
         // First check if this ProcessRecord is actually active for the pid.
         synchronized (mPidsSelfLocked) {
             ProcessRecord curProc = mPidsSelfLocked.get(pid);
@@ -3704,6 +3710,8 @@
         if (!app.killed) {
             if (!fromBinderDied) {
                 killProcessQuiet(pid);
+                mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                        ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
             }
             ProcessList.killProcessGroup(app.uid, pid);
             app.killed = true;
@@ -4727,7 +4735,7 @@
             cleanupAppInLaunchingProvidersLocked(app, true);
             // Take care of any services that are waiting for the process.
             mServices.processStartTimedOutLocked(app);
-            app.kill("start timeout", true);
+            app.kill("start timeout", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true);
             if (app.isolated) {
                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
             }
@@ -4814,6 +4822,8 @@
             if (pid > 0 && pid != MY_PID) {
                 killProcessQuiet(pid);
                 //TODO: killProcessGroup(app.info.uid, pid);
+                mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                        ApplicationExitInfo.SUBREASON_UNKNOWN, "attach failed");
             } else {
                 try {
                     thread.scheduleExit();
@@ -5153,7 +5163,7 @@
         }
 
         if (badApp) {
-            app.kill("error during init", true);
+            app.kill("error during init", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true);
             handleAppDiedLocked(app, false, true);
             return false;
         }
@@ -7544,7 +7554,7 @@
                     proc.info.uid);
             final long ident = Binder.clearCallingIdentity();
             try {
-                appDiedLocked(proc);
+                appDiedLocked(proc, "unstable content provider");
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -8856,7 +8866,7 @@
                 }
                 int adj = proc.setAdj;
                 if (adj >= worstType && !proc.killedByAm) {
-                    proc.kill(reason, true);
+                    proc.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
                     killed = true;
                 }
             }
@@ -8904,7 +8914,7 @@
 
                 final int adj = proc.setAdj;
                 if (adj > belowAdj && !proc.killedByAm) {
-                    proc.kill(reason, true);
+                    proc.kill(reason, ApplicationExitInfo.REASON_PERMISSION_CHANGE, true);
                     killed = true;
                 }
             }
@@ -8912,6 +8922,26 @@
         return killed;
     }
 
+    /**
+     * Similar to {@link #killPids} but killing will be delayed until the device is idle
+     * and the given process is imperceptible.
+     */
+    @Override
+    public void killProcessesWhenImperceptible(int[] pids, String reason) {
+        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission "
+                    + android.Manifest.permission.FORCE_STOP_PACKAGES);
+        }
+        int callerUid = Binder.getCallingUid();
+        long iden = Binder.clearCallingIdentity();
+        try {
+            mProcessList.killProcessesWhenImperceptible(pids, reason, callerUid);
+        } finally {
+            Binder.restoreCallingIdentity(iden);
+        }
+    }
+
     @Override
     public void hang(final IBinder who, boolean allowRestart) {
         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
@@ -9048,7 +9078,10 @@
                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
                             Slog.wtfQuiet(TAG, sb.toString());
                             proc.kill("idle maint (pss " + proc.lastPss
-                                    + " from " + proc.initialIdlePss + ")", true);
+                                    + " from " + proc.initialIdlePss + ")",
+                                    ApplicationExitInfo.REASON_OTHER,
+                                    ApplicationExitInfo.SUBREASON_MEMORY_PRESSURE,
+                                    true);
                         }
                     }
                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
@@ -9145,6 +9178,7 @@
             // Make sure we have the current profile info, since it is needed for security checks.
             mUserController.onSystemReady();
             mAppOpsService.systemReady();
+            mProcessList.onSystemReady();
             mSystemReady = true;
             t.traceEnd();
         }
@@ -9674,7 +9708,7 @@
      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
      * to append various headers to the dropbox log text.
      */
-    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
+    void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
             StringBuilder sb) {
         // Watchdog thread ends up invoking this function (with
         // a null ProcessRecord) to add the stack file to dropbox.
@@ -9972,6 +10006,67 @@
     }
 
     @Override
+    public ParceledListSlice<ApplicationExitInfo> getHistoricalProcessExitReasons(
+            String packageName, int pid, int maxNum, int userId) {
+        enforceNotIsolatedCaller("getHistoricalProcessExitReasons");
+
+        // For the simplification, we don't support USER_ALL nor USER_CURRENT here.
+        if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_CURRENT) {
+            throw new IllegalArgumentException("Unsupported userId");
+        }
+
+        final int callingPid = Binder.getCallingPid();
+        final int callingUid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getCallingUserId();
+        mUserController.handleIncomingUser(callingPid, callingUid, userId, true, ALLOW_NON_FULL,
+                "getHistoricalProcessExitReasons", null);
+
+        final ArrayList<ApplicationExitInfo> results = new ArrayList<ApplicationExitInfo>();
+        if (!TextUtils.isEmpty(packageName)) {
+            final int uid = enforceDumpPermissionForPackage(packageName, userId, callingUid,
+                      "getHistoricalProcessExitReasons");
+            if (uid != Process.INVALID_UID) {
+                mProcessList.mAppExitInfoTracker.getExitInfo(
+                        packageName, uid, pid, maxNum, results);
+            }
+        } else {
+            // If no package name is given, use the caller's uid as the filter uid.
+            mProcessList.mAppExitInfoTracker.getExitInfo(
+                    packageName, callingUid, pid, maxNum, results);
+        }
+
+        return new ParceledListSlice<ApplicationExitInfo>(results);
+    }
+
+    /**
+     * Check if the calling process has the permission to dump given package,
+     * throw SecurityException if it doesn't have the permission.
+     *
+     * @return The UID of the given package, or {@link android.os.Process#INVALID_UID}
+     *         if the package is not found.
+     */
+    private int enforceDumpPermissionForPackage(String packageName, int userId, int callingUid,
+            String function) {
+        long identity = Binder.clearCallingIdentity();
+        int uid = Process.INVALID_UID;
+        try {
+            uid = mPackageManagerInt.getPackageUid(packageName,
+                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        if (uid == Process.INVALID_UID) {
+            return Process.INVALID_UID;
+        }
+        if (UserHandle.getAppId(uid) != UserHandle.getAppId(callingUid)) {
+            // Requires the DUMP permission if the target package doesn't belong
+            // to the caller.
+            enforceCallingPermission(android.Manifest.permission.DUMP, function);
+        }
+        return uid;
+    }
+
+    @Override
     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
         if (outState == null) {
             throw new IllegalArgumentException("outState is null");
@@ -10150,6 +10245,12 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
+            mProcessList.mAppExitInfoTracker.dumpHistoryProcessExitInfo(pw, dumpPackage);
+            pw.println();
+            if (dumpAll) {
+                pw.println("-------------------------------------------------------------------"
+                        + "------------");
+            }
             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
             pw.println();
             if (dumpAll) {
@@ -10448,6 +10549,12 @@
                 synchronized (this) {
                     dumpUsersLocked(pw);
                 }
+            } else if ("exit-info".equals(cmd)) {
+                if (opti < args.length) {
+                    dumpPackage = args[opti];
+                    opti++;
+                }
+                mProcessList.mAppExitInfoTracker.dumpHistoryProcessExitInfo(pw, dumpPackage);
             } else {
                 // Dumping a single activity?
                 if (!mAtmInternal.dumpActivity(fd, pw, cmd, args, opti, dumpAll,
@@ -14061,7 +14168,9 @@
                     capp.kill("depends on provider "
                             + cpr.name.flattenToShortString()
                             + " in dying proc " + (proc != null ? proc.processName : "??")
-                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
+                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")",
+                            ApplicationExitInfo.REASON_OTHER,
+                            true);
                 }
             } else if (capp.thread != null && conn.provider.provider != null) {
                 try {
@@ -14146,6 +14255,7 @@
 
         // Take care of any launching providers waiting for this process.
         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
+            mProcessList.noteProcessDiedLocked(app);
             restart = true;
         }
 
@@ -14242,6 +14352,7 @@
         mProcessesOnHold.remove(app);
 
         mAtmInternal.onCleanUpApplicationRecord(app.getWindowProcessController());
+        mProcessList.noteProcessDiedLocked(app);
 
         if (restart && !app.isolated) {
             // We have components that still need to be running in the
@@ -16968,7 +17079,10 @@
                                     uptimeSince, cputimeUsed);
                         }
                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
-                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
+                                + " dur=" + checkDur + " limit=" + cpuLimit,
+                                ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
+                                ApplicationExitInfo.SUBREASON_EXCESSIVE_CPU,
+                                true);
                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList.mPkgList);
                         for (int ipkg = app.pkgList.size() - 1; ipkg >= 0; ipkg--) {
                             ProcessStats.ProcessStateHolder holder = app.pkgList.valueAt(ipkg);
@@ -17602,7 +17716,10 @@
                     + (app.thread != null ? app.thread.asBinder() : null)
                     + ")\n");
                 if (app.pid > 0 && app.pid != MY_PID) {
-                    app.kill("empty", false);
+                    app.kill("empty",
+                            ApplicationExitInfo.REASON_OTHER,
+                            ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
+                            false);
                 } else if (app.thread != null) {
                     try {
                         app.thread.scheduleExit();
@@ -18432,7 +18549,7 @@
                     final ProcessRecord pr = (ProcessRecord) wpc.mOwner;
                     if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
                             && pr.curReceivers.isEmpty()) {
-                        pr.kill("remove task", true);
+                        pr.kill("remove task", ApplicationExitInfo.REASON_OTHER, true);
                     } else {
                         // We delay killing processes that are not in the background or running a
                         // receiver.
@@ -19237,6 +19354,13 @@
             return false;
         }
 
+        /**
+         * Return the process list instance
+         */
+        public ProcessList getProcessList(ActivityManagerService service) {
+            return new ProcessList();
+        }
+
         private boolean ensureHasNetworkManagementInternal() {
             if (mNmi == null) {
                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d7ad1c2..e7d6eb7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -91,7 +91,6 @@
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.MemInfoReader;
-import com.android.internal.util.Preconditions;
 import com.android.server.compat.PlatformCompat;
 
 import java.io.BufferedReader;
@@ -217,6 +216,8 @@
                     return runSetWatchHeap(pw);
                 case "clear-watch-heap":
                     return runClearWatchHeap(pw);
+                case "clear-exit-info":
+                    return runClearExitInfo(pw);
                 case "bug-report":
                     return runBugReport(pw);
                 case "force-stop":
@@ -1019,6 +1020,30 @@
         return 0;
     }
 
+    int runClearExitInfo(PrintWriter pw) throws RemoteException {
+        mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
+                "runClearExitInfo()");
+        String opt;
+        int userId = UserHandle.USER_CURRENT;
+        String packageName = null;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                packageName = opt;
+            }
+        }
+        if (userId == UserHandle.USER_CURRENT) {
+            UserInfo user = mInterface.getCurrentUser();
+            if (user == null) {
+                return -1;
+            }
+            userId = user.id;
+        }
+        mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(packageName, userId);
+        return 0;
+    }
+
     int runBugReport(PrintWriter pw) throws RemoteException {
         String opt;
         boolean fullBugreport = true;
@@ -1145,7 +1170,7 @@
 
         static final int RESULT_ANR_DIALOG = 0;
         static final int RESULT_ANR_KILL = 1;
-        static final int RESULT_ANR_WAIT = 1;
+        static final int RESULT_ANR_WAIT = 2;
 
         int mResult;
 
@@ -3008,6 +3033,7 @@
             pw.println("    s[ervices] [COMP_SPEC ...]: service state");
             pw.println("    allowed-associations: current package association restrictions");
             pw.println("    as[sociations]: tracked app associations");
+            pw.println("    exit-info [PACKAGE_NAME]: historical process exit information");
             pw.println("    lmk: stats on low memory killer");
             pw.println("    lru: raw LRU process list");
             pw.println("    binder-proxies: stats on binder objects and IPCs");
@@ -3142,6 +3168,8 @@
             pw.println("      above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
             pw.println("  clear-watch-heap");
             pw.println("      Clear the previously set-watch-heap.");
+            pw.println("  clear-exit-info [--user <USER_ID> | all | current] [package]");
+            pw.println("      Clear the process exit-info for given package");
             pw.println("  bug-report [--progress | --telephony]");
             pw.println("      Request bug report generation; will launch a notification");
             pw.println("        when done to select where it should be delivered. Options are:");
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 8071f52..145f91b 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -29,6 +29,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ApplicationErrorReport;
+import android.app.ApplicationExitInfo;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
@@ -315,11 +316,23 @@
     }
 
     void killAppAtUserRequestLocked(ProcessRecord app) {
-        app.getDialogController().clearAllErrorDialogs();
-        killAppImmediateLocked(app, "user-terminated", "user request after error");
+        ProcessRecord.ErrorDialogController controller =
+                app.getDialogController();
+
+        int reasonCode = ApplicationExitInfo.REASON_ANR;
+        int subReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
+        if (controller.hasDebugWaitingDialog()) {
+            reasonCode = ApplicationExitInfo.REASON_OTHER;
+            subReason = ApplicationExitInfo.SUBREASON_WAIT_FOR_DEBUGGER;
+        }
+
+        controller.clearAllErrorDialogs();
+        killAppImmediateLocked(app, reasonCode, subReason,
+                "user-terminated", "user request after error");
     }
 
-    private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) {
+    private void killAppImmediateLocked(ProcessRecord app, int reasonCode, int subReason,
+            String reason, String killReason) {
         app.setCrashing(false);
         app.crashingReport = null;
         app.setNotResponding(false);
@@ -327,7 +340,7 @@
         if (app.pid > 0 && app.pid != MY_PID) {
             handleAppCrashLocked(app, reason,
                     null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
-            app.kill(killReason, true);
+            app.kill(killReason, reasonCode, subReason, true);
         }
     }
 
@@ -381,7 +394,9 @@
             mService.mHandler.postDelayed(
                     () -> {
                         synchronized (mService) {
-                            killAppImmediateLocked(p, "forced", "killed for invalid state");
+                            killAppImmediateLocked(p, ApplicationExitInfo.REASON_OTHER,
+                                    ApplicationExitInfo.SUBREASON_UNKNOWN,
+                                    "forced", "killed for invalid state");
                         }
                     },
                     5000L);
@@ -422,6 +437,13 @@
         if (r != null) {
             mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
                     PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+            mService.mProcessList.noteAppKill(r, (crashInfo != null
+                      && "Native crash".equals(crashInfo.exceptionClassName))
+                      ? ApplicationExitInfo.REASON_CRASH_NATIVE
+                      : ApplicationExitInfo.REASON_CRASH,
+                      ApplicationExitInfo.SUBREASON_UNKNOWN,
+                    "crash");
         }
 
         final int relaunchReason = r != null
@@ -488,7 +510,8 @@
                 stopReportingCrashesLocked(r);
             }
             if (res == AppErrorDialog.RESTART) {
-                mService.mProcessList.removeProcessLocked(r, false, true, "crash");
+                mService.mProcessList.removeProcessLocked(r, false, true, "crash",
+                        ApplicationExitInfo.REASON_CRASH);
                 if (taskId != INVALID_TASK_ID) {
                     try {
                         mService.startActivityFromRecents(taskId,
@@ -506,7 +529,8 @@
                     // Kill it with fire!
                     mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
                     if (!r.isPersistent()) {
-                        mService.mProcessList.removeProcessLocked(r, false, false, "crash");
+                        mService.mProcessList.removeProcessLocked(r, false, false, "crash",
+                                ApplicationExitInfo.REASON_CRASH);
                         mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
                     }
                 } finally {
@@ -549,22 +573,26 @@
 
         return mService.mAtmInternal.handleAppCrashInActivityController(
                 name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace, () -> {
-            if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
-                    && "Native crash".equals(crashInfo.exceptionClassName)) {
-                Slog.w(TAG, "Skip killing native crashed app " + name
-                        + "(" + pid + ") during testing");
-            } else {
-                Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request");
-                if (r != null) {
-                    if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) {
-                        r.kill("crash", true);
-                    }
+                if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
+                        && "Native crash".equals(crashInfo.exceptionClassName)) {
+                    Slog.w(TAG, "Skip killing native crashed app " + name
+                            + "(" + pid + ") during testing");
                 } else {
-                    // Huh.
-                    Process.killProcess(pid);
-                    ProcessList.killProcessGroup(uid, pid);
+                    Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request");
+                    if (r != null) {
+                        if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) {
+                            r.kill("crash", ApplicationExitInfo.REASON_CRASH, true);
+                        }
+                    } else {
+                        // Huh.
+                        Process.killProcess(pid);
+                        ProcessList.killProcessGroup(uid, pid);
+                        mService.mProcessList.noteAppKill(pid, uid,
+                                ApplicationExitInfo.REASON_CRASH,
+                                ApplicationExitInfo.SUBREASON_UNKNOWN,
+                                "crash");
+                    }
                 }
-            }
         });
     }
 
@@ -719,7 +747,8 @@
                 // Don't let services in this process be restarted and potentially
                 // annoy the user repeatedly.  Unless it is persistent, since those
                 // processes run critical code.
-                mService.mProcessList.removeProcessLocked(app, false, tryAgain, "crash");
+                mService.mProcessList.removeProcessLocked(app, false, tryAgain, "crash",
+                        ApplicationExitInfo.REASON_CRASH);
                 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
                 if (!showBackground) {
                     return false;
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
new file mode 100644
index 0000000..6e135d6
--- /dev/null
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -0,0 +1,1302 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.RunningAppProcessInfo.procStateToImportance;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.app.ApplicationExitInfo;
+import android.app.ApplicationExitInfo.Reason;
+import android.app.ApplicationExitInfo.SubReason;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.icu.text.SimpleDateFormat;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.system.OsConstants;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Pair;
+import android.util.Pools.SynchronizedPool;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.ProcessMap;
+import com.android.server.IoThread;
+import com.android.server.SystemServiceManager;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+
+/**
+ * A class to manage all the {@link android.app.ApplicationExitInfo} records.
+ */
+public final class AppExitInfoTracker {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppExitInfoTracker" : TAG_AM;
+
+    /**
+     * Interval of persisting the app exit info to persistent storage.
+     */
+    private static final long APP_EXIT_INFO_PERSIST_INTERVAL = TimeUnit.MINUTES.toMillis(30);
+
+    /** These are actions that the forEachPackage should take after each iteration */
+    private static final int FOREACH_ACTION_NONE = 0;
+    private static final int FOREACH_ACTION_REMOVE_PACKAGE = 1;
+    private static final int FOREACH_ACTION_STOP_ITERATION = 2;
+
+    private static final int APP_EXIT_RAW_INFO_POOL_SIZE = 8;
+
+    @VisibleForTesting
+    static final String APP_EXIT_INFO_FILE = "procexitinfo";
+
+    private final Object mLock = new Object();
+
+    /**
+     * Initialized in {@link #init} and read-only after that.
+     */
+    private ActivityManagerService mService;
+
+    /**
+     * Initialized in {@link #init} and read-only after that.
+     */
+    private KillHandler mKillHandler;
+
+    /**
+     * The task to persist app process exit info
+     */
+    @GuardedBy("mLock")
+    private Runnable mAppExitInfoPersistTask = null;
+
+    /**
+     * Last time(in ms) since epoch that the app exit info was persisted into persistent storage.
+     */
+    @GuardedBy("mLock")
+    private long mLastAppExitInfoPersistTimestamp = 0L;
+
+    /**
+     * Retention policy: keep up to X historical exit info per package.
+     *
+     * Initialized in {@link #init} and read-only after that.
+     * Not lock is needed.
+     */
+    private int mAppExitInfoHistoryListSize;
+
+    /*
+     * PackageName/uid -> [pid/info, ...] holder, the uid here is the package uid.
+     */
+    @GuardedBy("mLock")
+    private final ProcessMap<AppExitInfoContainer> mData;
+
+    /** A pool of raw {@link android.app.ApplicationExitInfo} records. */
+    @GuardedBy("mService")
+    private final SynchronizedPool<ApplicationExitInfo> mRawRecordsPool;
+
+    /**
+     * Wheather or not we've loaded the historical app process exit info from
+     * persistent storage.
+     */
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    boolean mAppExitInfoLoaded = false;
+
+    /**
+     * Temporary list being used to filter/sort intermediate results in {@link #getExitInfo}.
+     */
+    @GuardedBy("mLock")
+    final ArrayList<ApplicationExitInfo> mTmpInfoList = new ArrayList<ApplicationExitInfo>();
+
+    /**
+     * Temporary list being used to filter/sort intermediate results in {@link #getExitInfo}.
+     */
+    @GuardedBy("mLock")
+    final ArrayList<ApplicationExitInfo> mTmpInfoList2 = new ArrayList<ApplicationExitInfo>();
+
+    /**
+     * The path to the historical proc exit info file, persisted in the storage.
+     */
+    @VisibleForTesting
+    File mProcExitInfoFile;
+
+    /**
+     * Mapping between the isolated UID to its application uid.
+     */
+    final IsolatedUidRecords mIsolatedUidRecords =
+            new IsolatedUidRecords();
+
+    /**
+     * Bookkeeping app process exit info from Zygote.
+     */
+    final AppExitInfoExternalSource mAppExitInfoSourceZygote =
+            new AppExitInfoExternalSource("zygote", null);
+
+    /**
+     * Bookkeeping low memory kills info from lmkd.
+     */
+    final AppExitInfoExternalSource mAppExitInfoSourceLmkd =
+            new AppExitInfoExternalSource("lmkd", ApplicationExitInfo.REASON_LOW_MEMORY);
+
+    AppExitInfoTracker() {
+        mData = new ProcessMap<AppExitInfoContainer>();
+        mRawRecordsPool = new SynchronizedPool<ApplicationExitInfo>(APP_EXIT_RAW_INFO_POOL_SIZE);
+    }
+
+    void init(ActivityManagerService service, Looper looper) {
+        mService = service;
+        mKillHandler = new KillHandler(looper);
+        mProcExitInfoFile = new File(SystemServiceManager.ensureSystemDir(), APP_EXIT_INFO_FILE);
+
+        mAppExitInfoHistoryListSize = service.mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_app_exit_info_history_list_size);
+    }
+
+    void onSystemReady() {
+        // Read the sysprop set by lmkd and set this to persist so app could read it.
+        SystemProperties.set("persist.sys.lmk.reportkills",
+                Boolean.toString(SystemProperties.getBoolean("sys.lmk.reportkills", false)));
+        registerForUserRemoval();
+        registerForPackageRemoval();
+        IoThread.getHandler().post(this::loadExistingProcessExitInfo);
+    }
+
+    @GuardedBy("mService")
+    void scheduleNoteProcessDiedLocked(final ProcessRecord app) {
+        if (app == null || app.info == null) {
+            return;
+        }
+
+        synchronized (mLock) {
+            if (!mAppExitInfoLoaded) {
+                return;
+            }
+        }
+        // The current thread is holding the global lock, let's extract the info from it
+        // and schedule the info note task in the kill handler.
+        mKillHandler.obtainMessage(KillHandler.MSG_PROC_DIED, obtainRawRecordLocked(app))
+                .sendToTarget();
+    }
+
+    void scheduleNoteAppKill(final ProcessRecord app, final @Reason int reason,
+            final @SubReason int subReason, final String msg) {
+        synchronized (mLock) {
+            if (!mAppExitInfoLoaded) {
+                return;
+            }
+        }
+        synchronized (mService) {
+            if (app == null || app.info == null) {
+                return;
+            }
+
+            ApplicationExitInfo raw = obtainRawRecordLocked(app);
+            raw.setReason(reason);
+            raw.setSubReason(subReason);
+            raw.setDescription(msg);
+            mKillHandler.obtainMessage(KillHandler.MSG_APP_KILL, raw).sendToTarget();
+        }
+    }
+
+    void scheduleNoteAppKill(final int pid, final int uid, final @Reason int reason,
+            final @SubReason int subReason, final String msg) {
+        synchronized (mLock) {
+            if (!mAppExitInfoLoaded) {
+                return;
+            }
+        }
+        synchronized (mService) {
+            ProcessRecord app;
+            synchronized (mService.mPidsSelfLocked) {
+                app = mService.mPidsSelfLocked.get(pid);
+            }
+            if (app == null) {
+                if (DEBUG_PROCESSES) {
+                    Slog.w(TAG, "Skipping saving the kill reason for pid " + pid
+                            + "(uid=" + uid + ") since its process record is not found");
+                }
+            } else {
+                scheduleNoteAppKill(app, reason, subReason, msg);
+            }
+        }
+    }
+
+    interface LmkdKillListener {
+        /**
+         * Called when there is a process kill by lmkd.
+         */
+        void onLmkdKillOccurred(int pid, int uid);
+    }
+
+    void setLmkdKillListener(final LmkdKillListener listener) {
+        synchronized (mLock) {
+            mAppExitInfoSourceLmkd.setOnProcDiedListener((pid, uid) ->
+                    listener.onLmkdKillOccurred(pid, uid));
+        }
+    }
+
+    /** Called when there is a low memory kill */
+    void scheduleNoteLmkdProcKilled(final int pid, final int uid) {
+        mKillHandler.obtainMessage(KillHandler.MSG_LMKD_PROC_KILLED, pid, uid)
+                .sendToTarget();
+    }
+
+    private void scheduleChildProcDied(int pid, int uid, int status) {
+        mKillHandler.obtainMessage(KillHandler.MSG_CHILD_PROC_DIED, pid, uid, (Integer) status)
+                .sendToTarget();
+    }
+
+    /** Calls when zygote sends us SIGCHLD */
+    void handleZygoteSigChld(int pid, int uid, int status) {
+        if (DEBUG_PROCESSES) {
+            Slog.i(TAG, "Got SIGCHLD from zygote: pid=" + pid + ", uid=" + uid
+                    + ", status=" + Integer.toHexString(status));
+        }
+        scheduleChildProcDied(pid, uid, status);
+    }
+
+    /**
+     * Main routine to create or update the {@link android.app.ApplicationExitInfo} for the given
+     * ProcessRecord, also query the zygote and lmkd records to make the information more accurate.
+     */
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    void handleNoteProcessDiedLocked(final ApplicationExitInfo raw) {
+        if (raw != null) {
+            if (DEBUG_PROCESSES) {
+                Slog.i(TAG, "Update process exit info for " + raw.getPackageName()
+                        + "(" + raw.getPid() + "/u" + raw.getRealUid() + ")");
+            }
+
+            ApplicationExitInfo info = getExitInfo(raw.getPackageName(),
+                    raw.getPackageUid(), raw.getPid());
+
+            // query zygote and lmkd to get the exit info, and clear the saved info
+            Pair<Long, Object> zygote = mAppExitInfoSourceZygote.remove(
+                    raw.getPid(), raw.getRealUid());
+            Pair<Long, Object> lmkd = mAppExitInfoSourceLmkd.remove(
+                    raw.getPid(), raw.getRealUid());
+            mIsolatedUidRecords.removeIsolatedUid(raw.getRealUid());
+
+            if (info == null) {
+                info = addExitInfoLocked(raw);
+            }
+
+            if (lmkd != null) {
+                updateExistingExitInfoRecordLocked(info, null,
+                        ApplicationExitInfo.REASON_LOW_MEMORY);
+            } else if (zygote != null) {
+                updateExistingExitInfoRecordLocked(info, (Integer) zygote.second, null);
+            }
+        }
+    }
+
+    /**
+     * Make note when ActivityManagerService decides to kill an application process.
+     */
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    void handleNoteAppKillLocked(final ApplicationExitInfo raw) {
+        ApplicationExitInfo info = getExitInfo(
+                raw.getPackageName(), raw.getPackageUid(), raw.getPid());
+
+        if (info == null) {
+            addExitInfoLocked(raw);
+        } else {
+            // always override the existing info since we are now more informational.
+            info.setReason(raw.getReason());
+            info.setStatus(0);
+            info.setTimestamp(System.currentTimeMillis());
+            info.setDescription(raw.getDescription());
+        }
+    }
+
+    @GuardedBy("mLock")
+    private ApplicationExitInfo addExitInfoLocked(ApplicationExitInfo raw) {
+        if (!mAppExitInfoLoaded) {
+            Slog.w(TAG, "Skipping saving the exit info due to ongoing loading from storage");
+            return null;
+        }
+
+        final ApplicationExitInfo info = new ApplicationExitInfo(raw);
+        final String[] packages = raw.getPackageList();
+        final int uid = raw.getPackageUid();
+        for (int i = 0; i < packages.length; i++) {
+            addExitInfoInner(packages[i], uid, info);
+        }
+
+        schedulePersistProcessExitInfo(false);
+
+        return info;
+    }
+
+    /**
+     * Update an existing {@link android.app.ApplicationExitInfo} record with given information.
+     */
+    @GuardedBy("mLock")
+    private void updateExistingExitInfoRecordLocked(ApplicationExitInfo info,
+            Integer status, Integer reason) {
+        if (info == null || !isFresh(info.getTimestamp())) {
+            // if the record is way outdated, don't update it then (because of potential pid reuse)
+            return;
+        }
+        if (status != null) {
+            if (OsConstants.WIFEXITED(status)) {
+                info.setReason(ApplicationExitInfo.REASON_EXIT_SELF);
+                info.setStatus(OsConstants.WEXITSTATUS(status));
+            } else if (OsConstants.WIFSIGNALED(status)) {
+                if (info.getReason() == ApplicationExitInfo.REASON_UNKNOWN) {
+                    info.setReason(ApplicationExitInfo.REASON_SIGNALED);
+                    info.setStatus(OsConstants.WTERMSIG(status));
+                } else if (info.getReason() == ApplicationExitInfo.REASON_CRASH_NATIVE) {
+                    info.setStatus(OsConstants.WTERMSIG(status));
+                }
+            }
+        }
+        if (reason != null) {
+            info.setReason(reason);
+        }
+    }
+
+    /**
+     * Update an existing {@link android.app.ApplicationExitInfo} record with given information.
+     *
+     * @return true if a recond is updated
+     */
+    private boolean updateExitInfoIfNecessary(int pid, int uid, Integer status, Integer reason) {
+        synchronized (mLock) {
+            if (UserHandle.isIsolated(uid)) {
+                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+                if (k != null) {
+                    uid = k;
+                }
+            }
+            ArrayList<ApplicationExitInfo> tlist = mTmpInfoList;
+            tlist.clear();
+            final int targetUid = uid;
+            forEachPackage((packageName, records) -> {
+                AppExitInfoContainer container = records.get(targetUid);
+                if (container == null) {
+                    return FOREACH_ACTION_NONE;
+                }
+                tlist.clear();
+                container.getExitInfoLocked(pid, 1, tlist);
+                if (tlist.size() == 0) {
+                    return FOREACH_ACTION_NONE;
+                }
+                ApplicationExitInfo info = tlist.get(0);
+                if (info.getRealUid() != targetUid) {
+                    tlist.clear();
+                    return FOREACH_ACTION_NONE;
+                }
+                // Okay found it, update its reason.
+                updateExistingExitInfoRecordLocked(info, status, reason);
+
+                return FOREACH_ACTION_STOP_ITERATION;
+            });
+            return tlist.size() > 0;
+        }
+    }
+
+    /**
+     * Get the exit info with matching package name, filterUid and filterPid (if > 0)
+     */
+    @VisibleForTesting
+    void getExitInfo(final String packageName, final int filterUid,
+            final int filterPid, final int maxNum, final ArrayList<ApplicationExitInfo> results) {
+        synchronized (mLock) {
+            boolean emptyPackageName = TextUtils.isEmpty(packageName);
+            if (!emptyPackageName) {
+                // fast path
+                AppExitInfoContainer container = mData.get(packageName, filterUid);
+                if (container != null) {
+                    container.getExitInfoLocked(filterPid, maxNum, results);
+                }
+            } else {
+                // slow path
+                final ArrayList<ApplicationExitInfo> list = mTmpInfoList2;
+                list.clear();
+                // get all packages
+                forEachPackage((name, records) -> {
+                    AppExitInfoContainer container = records.get(filterUid);
+                    if (container != null) {
+                        mTmpInfoList.clear();
+                        results.addAll(container.toListLocked(mTmpInfoList, filterPid));
+                    }
+                    return AppExitInfoTracker.FOREACH_ACTION_NONE;
+                });
+
+                Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
+                int size = list.size();
+                if (maxNum > 0) {
+                    size = Math.min(size, maxNum);
+                }
+                for (int i = 0; i < size; i++) {
+                    results.add(list.get(i));
+                }
+                list.clear();
+            }
+        }
+    }
+
+    /**
+     * Return the first matching exit info record, for internal use, the parameters are not supposed
+     * to be empty.
+     */
+    private ApplicationExitInfo getExitInfo(final String packageName,
+            final int filterUid, final int filterPid) {
+        synchronized (mLock) {
+            ArrayList<ApplicationExitInfo> list = mTmpInfoList;
+            list.clear();
+            getExitInfo(packageName, filterUid, filterPid, 1, list);
+
+            ApplicationExitInfo info = list.size() > 0 ? list.get(0) : null;
+            list.clear();
+            return info;
+        }
+    }
+
+    @VisibleForTesting
+    void onUserRemoved(int userId) {
+        mAppExitInfoSourceZygote.removeByUserId(userId);
+        mAppExitInfoSourceLmkd.removeByUserId(userId);
+        mIsolatedUidRecords.removeByUserId(userId);
+        removeByUserId(userId);
+        schedulePersistProcessExitInfo(true);
+    }
+
+    @VisibleForTesting
+    void onPackageRemoved(String packageName, int uid, boolean allUsers) {
+        if (packageName != null) {
+            mAppExitInfoSourceZygote.removeByUid(uid, allUsers);
+            mAppExitInfoSourceLmkd.removeByUid(uid, allUsers);
+            mIsolatedUidRecords.removeAppUid(uid, allUsers);
+            removePackage(packageName, allUsers ? UserHandle.USER_ALL : UserHandle.getUserId(uid));
+            schedulePersistProcessExitInfo(true);
+        }
+    }
+
+    private void registerForUserRemoval() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_REMOVED);
+        mService.mContext.registerReceiverForAllUsers(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                if (userId < 1) return;
+                onUserRemoved(userId);
+            }
+        }, filter, null, mKillHandler);
+    }
+
+    private void registerForPackageRemoval() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addDataScheme("package");
+        mService.mContext.registerReceiverForAllUsers(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                int uid = intent.getIntExtra(Intent.EXTRA_UID, UserHandle.USER_NULL);
+                boolean allUsers = intent.getBooleanExtra(
+                        Intent.EXTRA_REMOVED_FOR_ALL_USERS, false);
+                onPackageRemoved(intent.getData().getSchemeSpecificPart(), uid, allUsers);
+            }
+        }, filter, null, mKillHandler);
+    }
+
+    /**
+     * Load the existing {@link android.app.ApplicationExitInfo} records from persistent storage.
+     */
+    @VisibleForTesting
+    void loadExistingProcessExitInfo() {
+        if (!mProcExitInfoFile.canRead()) {
+            synchronized (mLock) {
+                mAppExitInfoLoaded = true;
+            }
+            return;
+        }
+
+        FileInputStream fin = null;
+        try {
+            AtomicFile af = new AtomicFile(mProcExitInfoFile);
+            fin = af.openRead();
+            ProtoInputStream proto = new ProtoInputStream(fin);
+            for (int next = proto.nextField();
+                    next != ProtoInputStream.NO_MORE_FIELDS;
+                    next = proto.nextField()) {
+                switch (next) {
+                    case (int) AppsExitInfoProto.LAST_UPDATE_TIMESTAMP:
+                        synchronized (mLock) {
+                            mLastAppExitInfoPersistTimestamp =
+                                    proto.readLong(AppsExitInfoProto.LAST_UPDATE_TIMESTAMP);
+                        }
+                        break;
+                    case (int) AppsExitInfoProto.PACKAGES:
+                        loadPackagesFromProto(proto, next);
+                        break;
+                }
+            }
+        } catch (IOException | IllegalArgumentException | WireTypeMismatchException e) {
+            Slog.w(TAG, "Error in loading historical app exit info from persistent storage: " + e);
+        } finally {
+            if (fin != null) {
+                try {
+                    fin.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        synchronized (mLock) {
+            mAppExitInfoLoaded = true;
+        }
+    }
+
+    private void loadPackagesFromProto(ProtoInputStream proto, long fieldId)
+            throws IOException, WireTypeMismatchException {
+        long token = proto.start(fieldId);
+        String pkgName = "";
+        for (int next = proto.nextField();
+                next != ProtoInputStream.NO_MORE_FIELDS;
+                next = proto.nextField()) {
+            switch (next) {
+                case (int) AppsExitInfoProto.Package.PACKAGE_NAME:
+                    pkgName = proto.readString(AppsExitInfoProto.Package.PACKAGE_NAME);
+                    break;
+                case (int) AppsExitInfoProto.Package.USERS:
+                    AppExitInfoContainer container = new AppExitInfoContainer(
+                            mAppExitInfoHistoryListSize);
+                    int uid = container.readFromProto(proto, AppsExitInfoProto.Package.USERS);
+                    synchronized (mLock) {
+                        mData.put(pkgName, uid, container);
+                    }
+                    break;
+            }
+        }
+        proto.end(token);
+    }
+
+    /**
+     * Persist the existing {@link android.app.ApplicationExitInfo} records to storage.
+     */
+    @VisibleForTesting
+    void persistProcessExitInfo() {
+        AtomicFile af = new AtomicFile(mProcExitInfoFile);
+        FileOutputStream out = null;
+        long now = System.currentTimeMillis();
+        try {
+            out = af.startWrite();
+            ProtoOutputStream proto = new ProtoOutputStream(out);
+            proto.write(AppsExitInfoProto.LAST_UPDATE_TIMESTAMP, now);
+            synchronized (mLock) {
+                forEachPackage((packageName, records) -> {
+                    long token = proto.start(AppsExitInfoProto.PACKAGES);
+                    proto.write(AppsExitInfoProto.Package.PACKAGE_NAME, packageName);
+                    int uidArraySize = records.size();
+                    for (int j = 0; j < uidArraySize; j++) {
+                        records.valueAt(j).writeToProto(proto, AppsExitInfoProto.Package.USERS);
+                    }
+                    proto.end(token);
+                    return AppExitInfoTracker.FOREACH_ACTION_NONE;
+                });
+                mLastAppExitInfoPersistTimestamp = now;
+            }
+            proto.flush();
+            af.finishWrite(out);
+        } catch (IOException e) {
+            Slog.w(TAG, "Unable to write historical app exit info into persistent storage: " + e);
+            af.failWrite(out);
+        }
+        synchronized (mLock) {
+            mAppExitInfoPersistTask = null;
+        }
+    }
+
+    /**
+     * Schedule a task to persist the {@link android.app.ApplicationExitInfo} records to storage.
+     */
+    @VisibleForTesting
+    void schedulePersistProcessExitInfo(boolean immediately) {
+        synchronized (mLock) {
+            if (mAppExitInfoPersistTask == null || immediately) {
+                if (mAppExitInfoPersistTask != null) {
+                    IoThread.getHandler().removeCallbacks(mAppExitInfoPersistTask);
+                }
+                mAppExitInfoPersistTask = this::persistProcessExitInfo;
+                IoThread.getHandler().postDelayed(mAppExitInfoPersistTask,
+                        immediately ? 0 : APP_EXIT_INFO_PERSIST_INTERVAL);
+            }
+        }
+    }
+
+    /**
+     * Helper function for testing only.
+     */
+    @VisibleForTesting
+    void clearProcessExitInfo(boolean removeFile) {
+        synchronized (mLock) {
+            if (mAppExitInfoPersistTask != null) {
+                IoThread.getHandler().removeCallbacks(mAppExitInfoPersistTask);
+                mAppExitInfoPersistTask = null;
+            }
+            if (removeFile && mProcExitInfoFile != null) {
+                mProcExitInfoFile.delete();
+            }
+            mData.getMap().clear();
+        }
+    }
+
+    /**
+     * Helper function for shell command
+     */
+    void clearHistoryProcessExitInfo(String packageName, int userId) {
+        synchronized (mLock) {
+            if (TextUtils.isEmpty(packageName)) {
+                if (userId == UserHandle.USER_ALL) {
+                    mData.getMap().clear();
+                } else {
+                    removeByUserId(userId);
+                }
+            } else {
+                removePackage(packageName, userId);
+            }
+        }
+        schedulePersistProcessExitInfo(true);
+    }
+
+    void dumpHistoryProcessExitInfo(PrintWriter pw, String packageName) {
+        pw.println("ACTIVITY MANAGER LRU PROCESSES (dumpsys activity exit-info)");
+        SimpleDateFormat sdf = new SimpleDateFormat();
+        synchronized (mLock) {
+            pw.println("Last Timestamp of Persistence Into Persistent Storage: "
+                    + sdf.format(new Date(mLastAppExitInfoPersistTimestamp)));
+            if (TextUtils.isEmpty(packageName)) {
+                forEachPackage((name, records) -> {
+                    dumpHistoryProcessExitInfoLocked(pw, "  ", name, records, sdf);
+                    return AppExitInfoTracker.FOREACH_ACTION_NONE;
+                });
+            } else {
+                SparseArray<AppExitInfoContainer> array = mData.getMap().get(packageName);
+                if (array != null) {
+                    dumpHistoryProcessExitInfoLocked(pw, "  ", packageName, array, sdf);
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void dumpHistoryProcessExitInfoLocked(PrintWriter pw, String prefix,
+            String packageName, SparseArray<AppExitInfoContainer> array,
+            SimpleDateFormat sdf) {
+        pw.println(prefix + "package: " + packageName);
+        int size = array.size();
+        for (int i = 0; i < size; i++) {
+            pw.println(prefix + "  Historical Process Exit for userId=" + array.keyAt(i));
+            array.valueAt(i).dumpLocked(pw, prefix + "    ", sdf);
+        }
+    }
+
+    private void addExitInfoInner(String packageName, int userId, ApplicationExitInfo info) {
+        synchronized (mLock) {
+            AppExitInfoContainer container = mData.get(packageName, userId);
+            if (container == null) {
+                container = new AppExitInfoContainer(mAppExitInfoHistoryListSize);
+                if (UserHandle.isIsolated(info.getRealUid())) {
+                    Integer k = mIsolatedUidRecords.getUidByIsolatedUid(info.getRealUid());
+                    if (k != null) {
+                        container.mUid = k;
+                    }
+                } else {
+                    container.mUid = info.getRealUid();
+                }
+                mData.put(packageName, userId, container);
+            }
+            container.addExitInfoLocked(info);
+        }
+    }
+
+    private void forEachPackage(
+            BiFunction<String, SparseArray<AppExitInfoContainer>, Integer> callback) {
+        if (callback != null) {
+            synchronized (mLock) {
+                ArrayMap<String, SparseArray<AppExitInfoContainer>> map = mData.getMap();
+                for (int i = map.size() - 1; i >= 0; i--) {
+                    switch (callback.apply(map.keyAt(i), map.valueAt(i))) {
+                        case FOREACH_ACTION_REMOVE_PACKAGE:
+                            map.removeAt(i);
+                            break;
+                        case FOREACH_ACTION_STOP_ITERATION:
+                            i = 0;
+                            break;
+                        case FOREACH_ACTION_NONE:
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+    private void removePackage(String packageName, int userId) {
+        synchronized (mLock) {
+            if (userId == UserHandle.USER_ALL) {
+                mData.getMap().remove(packageName);
+            } else {
+                ArrayMap<String, SparseArray<AppExitInfoContainer>> map =
+                        mData.getMap();
+                SparseArray<AppExitInfoContainer> array = map.get(packageName);
+                if (array == null) {
+                    return;
+                }
+                for (int i = array.size() - 1; i >= 0; i--) {
+                    if (UserHandle.getUserId(array.keyAt(i)) == userId) {
+                        array.removeAt(i);
+                        break;
+                    }
+                }
+                if (array.size() == 0) {
+                    map.remove(packageName);
+                }
+            }
+        }
+    }
+
+    private void removeByUserId(final int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            synchronized (mLock) {
+                mData.getMap().clear();
+            }
+            return;
+        }
+        forEachPackage((packageName, records) -> {
+            for (int i = records.size() - 1; i >= 0; i--) {
+                if (UserHandle.getUserId(records.keyAt(i)) == userId) {
+                    records.removeAt(i);
+                    break;
+                }
+            }
+            return records.size() == 0 ? FOREACH_ACTION_REMOVE_PACKAGE : FOREACH_ACTION_NONE;
+        });
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mService")
+    ApplicationExitInfo obtainRawRecordLocked(ProcessRecord app) {
+        ApplicationExitInfo info = mRawRecordsPool.acquire();
+        if (info == null) {
+            info = new ApplicationExitInfo();
+        }
+
+        final int definingUid = app.hostingRecord != null ? app.hostingRecord.getDefiningUid() : 0;
+        info.setPid(app.pid);
+        info.setRealUid(app.uid);
+        info.setPackageUid(app.info.uid);
+        info.setDefiningUid(definingUid > 0 ? definingUid : app.info.uid);
+        info.setProcessName(app.processName);
+        info.setConnectionGroup(app.connectionGroup);
+        info.setPackageName(app.info.packageName);
+        info.setPackageList(app.getPackageList());
+        info.setReason(ApplicationExitInfo.REASON_UNKNOWN);
+        info.setStatus(0);
+        info.setImportance(procStateToImportance(app.setProcState));
+        info.setPss(app.lastMemInfo == null ? 0 : app.lastMemInfo.getTotalPss());
+        info.setRss(app.lastMemInfo == null ? 0 : app.lastMemInfo.getTotalRss());
+        info.setTimestamp(System.currentTimeMillis());
+
+        return info;
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mService")
+    void recycleRawRecordLocked(ApplicationExitInfo info) {
+        info.setProcessName(null);
+        info.setDescription(null);
+        info.setPackageList(null);
+
+        mRawRecordsPool.release(info);
+    }
+
+    /**
+     * A container class of {@link android.app.ApplicationExitInfo}
+     */
+    final class AppExitInfoContainer {
+        private SparseArray<ApplicationExitInfo> mInfos; // index is pid
+        private int mMaxCapacity;
+        private int mUid; // Application uid, not isolated uid.
+
+        AppExitInfoContainer(final int maxCapacity) {
+            mInfos = new SparseArray<ApplicationExitInfo>();
+            mMaxCapacity = maxCapacity;
+        }
+
+        @GuardedBy("mLock")
+        void getExitInfoLocked(final int filterPid, final int maxNum,
+                ArrayList<ApplicationExitInfo> results) {
+            if (filterPid > 0) {
+                ApplicationExitInfo r = mInfos.get(filterPid);
+                if (r != null) {
+                    results.add(r);
+                }
+            } else {
+                final int numRep = mInfos.size();
+                if (maxNum <= 0 || numRep <= maxNum) {
+                    // Return all records.
+                    for (int i = 0; i < numRep; i++) {
+                        results.add(mInfos.valueAt(i));
+                    }
+                    Collections.sort(results,
+                            (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
+                } else {
+                    if (maxNum == 1) {
+                        // Most of the caller might be only interested with the most recent one
+                        ApplicationExitInfo r = mInfos.valueAt(0);
+                        for (int i = 1; i < numRep; i++) {
+                            ApplicationExitInfo t = mInfos.valueAt(i);
+                            if (r.getTimestamp() < t.getTimestamp()) {
+                                r = t;
+                            }
+                        }
+                        results.add(r);
+                    } else {
+                        // Huh, need to sort it out then.
+                        ArrayList<ApplicationExitInfo> list = mTmpInfoList2;
+                        list.clear();
+                        for (int i = 0; i < numRep; i++) {
+                            list.add(mInfos.valueAt(i));
+                        }
+                        Collections.sort(list,
+                                (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
+                        for (int i = 0; i < maxNum; i++) {
+                            results.add(list.get(i));
+                        }
+                        list.clear();
+                    }
+                }
+            }
+        }
+
+        @GuardedBy("mLock")
+        void addExitInfoLocked(ApplicationExitInfo info) {
+            int size;
+            if ((size = mInfos.size()) >= mMaxCapacity) {
+                int oldestIndex = -1;
+                long oldestTimeStamp = Long.MAX_VALUE;
+                for (int i = 0; i < size; i++) {
+                    ApplicationExitInfo r = mInfos.valueAt(i);
+                    if (r.getTimestamp() < oldestTimeStamp) {
+                        oldestTimeStamp = r.getTimestamp();
+                        oldestIndex = i;
+                    }
+                }
+                if (oldestIndex >= 0) {
+                    mInfos.removeAt(oldestIndex);
+                }
+            }
+            mInfos.append(info.getPid(), info);
+        }
+
+        @GuardedBy("mLock")
+        void dumpLocked(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
+            ArrayList<ApplicationExitInfo> list = new ArrayList<ApplicationExitInfo>();
+            for (int i = mInfos.size() - 1; i >= 0; i--) {
+                list.add(mInfos.valueAt(i));
+            }
+            Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
+            int size = list.size();
+            for (int i = 0; i < size; i++) {
+                list.get(i).dump(pw, prefix + "  ", "#" + i, sdf);
+            }
+        }
+
+        @GuardedBy("mLock")
+        void writeToProto(ProtoOutputStream proto, long fieldId) {
+            long token = proto.start(fieldId);
+            proto.write(AppsExitInfoProto.Package.User.UID, mUid);
+            int size = mInfos.size();
+            for (int i = 0; i < size; i++) {
+                mInfos.valueAt(i).writeToProto(proto, AppsExitInfoProto.Package.User.APP_EXIT_INFO);
+            }
+            proto.end(token);
+        }
+
+        int readFromProto(ProtoInputStream proto, long fieldId)
+                throws IOException, WireTypeMismatchException {
+            long token = proto.start(fieldId);
+            for (int next = proto.nextField();
+                    next != ProtoInputStream.NO_MORE_FIELDS;
+                    next = proto.nextField()) {
+                switch (next) {
+                    case (int) AppsExitInfoProto.Package.User.UID:
+                        mUid = proto.readInt(AppsExitInfoProto.Package.User.UID);
+                        break;
+                    case (int) AppsExitInfoProto.Package.User.APP_EXIT_INFO:
+                        ApplicationExitInfo info = new ApplicationExitInfo();
+                        info.readFromProto(proto, AppsExitInfoProto.Package.User.APP_EXIT_INFO);
+                        mInfos.put(info.getPid(), info);
+                        break;
+                }
+            }
+            proto.end(token);
+            return mUid;
+        }
+
+        @GuardedBy("mLock")
+        List<ApplicationExitInfo> toListLocked(List<ApplicationExitInfo> list, int filterPid) {
+            if (list == null) {
+                list = new ArrayList<ApplicationExitInfo>();
+            }
+            for (int i = mInfos.size() - 1; i >= 0; i--) {
+                if (filterPid == 0 || filterPid == mInfos.keyAt(i)) {
+                    list.add(mInfos.valueAt(i));
+                }
+            }
+            return list;
+        }
+    }
+
+    /**
+     * Maintains the mapping between real UID and the application uid.
+     */
+    final class IsolatedUidRecords {
+        /**
+         * A mapping from application uid (with the userId) to isolated uids.
+         */
+        @GuardedBy("mLock")
+        private final SparseArray<ArraySet<Integer>> mUidToIsolatedUidMap;
+
+        /**
+         * A mapping from isolated uids to application uid (with the userId)
+         */
+        @GuardedBy("mLock")
+        private final SparseArray<Integer> mIsolatedUidToUidMap;
+
+        IsolatedUidRecords() {
+            mUidToIsolatedUidMap = new SparseArray<ArraySet<Integer>>();
+            mIsolatedUidToUidMap = new SparseArray<Integer>();
+        }
+
+        void addIsolatedUid(int isolatedUid, int uid) {
+            synchronized (mLock) {
+                ArraySet<Integer> set = mUidToIsolatedUidMap.get(uid);
+                if (set == null) {
+                    set = new ArraySet<Integer>();
+                    mUidToIsolatedUidMap.put(uid, set);
+                }
+                set.add(isolatedUid);
+
+                mIsolatedUidToUidMap.put(isolatedUid, uid);
+            }
+        }
+
+        Integer getUidByIsolatedUid(int isolatedUid) {
+            if (UserHandle.isIsolated(isolatedUid)) {
+                synchronized (mLock) {
+                    return mIsolatedUidToUidMap.get(isolatedUid);
+                }
+            }
+            return isolatedUid;
+        }
+
+        @GuardedBy("mLock")
+        private void removeAppUidLocked(int uid) {
+            ArraySet<Integer> set = mUidToIsolatedUidMap.get(uid);
+            if (set != null) {
+                for (int i = set.size() - 1; i >= 0; i--) {
+                    int isolatedUid = set.removeAt(i);
+                    mIsolatedUidToUidMap.remove(isolatedUid);
+                }
+            }
+        }
+
+        void removeAppUid(int uid, boolean allUsers) {
+            synchronized (mLock) {
+                if (allUsers) {
+                    uid = UserHandle.getAppId(uid);
+                    for (int i = mUidToIsolatedUidMap.size() - 1; i >= 0; i--) {
+                        int u = mUidToIsolatedUidMap.keyAt(i);
+                        if (uid == UserHandle.getAppId(u)) {
+                            removeAppUidLocked(u);
+                        }
+                        mUidToIsolatedUidMap.removeAt(i);
+                    }
+                } else {
+                    removeAppUidLocked(uid);
+                    mUidToIsolatedUidMap.remove(uid);
+                }
+            }
+        }
+
+        int removeIsolatedUid(int isolatedUid) {
+            if (!UserHandle.isIsolated(isolatedUid)) {
+                return isolatedUid;
+            }
+            synchronized (mLock) {
+                int uid = mIsolatedUidToUidMap.get(isolatedUid, -1);
+                if (uid == -1) {
+                    return isolatedUid;
+                }
+                mIsolatedUidToUidMap.remove(isolatedUid);
+                ArraySet<Integer> set = mUidToIsolatedUidMap.get(uid);
+                if (set != null) {
+                    set.remove(isolatedUid);
+                }
+                // let the ArraySet stay in the mUidToIsolatedUidMap even if it's empty
+                return uid;
+            }
+        }
+
+        void removeByUserId(int userId) {
+            if (userId == UserHandle.USER_CURRENT) {
+                userId = mService.mUserController.getCurrentUserId();
+            }
+            synchronized (mLock) {
+                if (userId == UserHandle.USER_ALL) {
+                    mIsolatedUidToUidMap.clear();
+                    mUidToIsolatedUidMap.clear();
+                    return;
+                }
+                for (int i = mIsolatedUidToUidMap.size() - 1; i >= 0; i--) {
+                    int isolatedUid = mIsolatedUidToUidMap.keyAt(i);
+                    int uid = mIsolatedUidToUidMap.valueAt(i);
+                    if (UserHandle.getUserId(uid) == userId) {
+                        mIsolatedUidToUidMap.removeAt(i);
+                        mUidToIsolatedUidMap.remove(uid);
+                    }
+                }
+            }
+        }
+    }
+
+    final class KillHandler extends Handler {
+        static final int MSG_LMKD_PROC_KILLED = 4101;
+        static final int MSG_CHILD_PROC_DIED = 4102;
+        static final int MSG_PROC_DIED = 4103;
+        static final int MSG_APP_KILL = 4104;
+
+        KillHandler(Looper looper) {
+            super(looper, null, true);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_LMKD_PROC_KILLED:
+                    mAppExitInfoSourceLmkd.onProcDied(msg.arg1 /* pid */, msg.arg2 /* uid */,
+                            null /* status */);
+                    break;
+                case MSG_CHILD_PROC_DIED:
+                    mAppExitInfoSourceZygote.onProcDied(msg.arg1 /* pid */, msg.arg2 /* uid */,
+                            (Integer) msg.obj /* status */);
+                    break;
+                case MSG_PROC_DIED: {
+                    ApplicationExitInfo raw = (ApplicationExitInfo) msg.obj;
+                    synchronized (mLock) {
+                        handleNoteProcessDiedLocked(raw);
+                    }
+                    synchronized (mService) {
+                        recycleRawRecordLocked(raw);
+                    }
+                }
+                break;
+                case MSG_APP_KILL: {
+                    ApplicationExitInfo raw = (ApplicationExitInfo) msg.obj;
+                    synchronized (mLock) {
+                        handleNoteAppKillLocked(raw);
+                    }
+                    synchronized (mService) {
+                        recycleRawRecordLocked(raw);
+                    }
+                }
+                break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    }
+
+    private static boolean isFresh(long timestamp) {
+        // A process could be dying but being stuck in some state, i.e.,
+        // being TRACED by tombstoned, thus the zygote receives SIGCHILD
+        // way after we already knew the kill (maybe because we did the kill :P),
+        // so here check if the last known kill information is "fresh" enough.
+        long now = System.currentTimeMillis();
+
+        return (timestamp + AppExitInfoExternalSource.APP_EXIT_INFO_FRESHNESS_MS) >= now;
+    }
+
+    /**
+     * Keep the raw information about app kills from external sources, i.e., lmkd
+     */
+    final class AppExitInfoExternalSource {
+        private static final long APP_EXIT_INFO_FRESHNESS_MS = 300 * 1000;
+
+        /**
+         * A mapping between uid -> pid -> {timestamp, extra info(Nullable)}.
+         * The uid here is the application uid, not the isolated uid.
+         */
+        @GuardedBy("mLock")
+        private final SparseArray<SparseArray<Pair<Long, Object>>> mData;
+
+        /** A tag for logging only */
+        private final String mTag;
+
+        /** A preset reason in case a proc dies */
+        private final Integer mPresetReason;
+
+        /** A callback that will be notified when a proc dies */
+        private BiConsumer<Integer, Integer> mProcDiedListener;
+
+        AppExitInfoExternalSource(String tag, Integer reason) {
+            mData = new SparseArray<SparseArray<Pair<Long, Object>>>();
+            mTag = tag;
+            mPresetReason = reason;
+        }
+
+        void add(int pid, int uid, Object extra) {
+            if (UserHandle.isIsolated(uid)) {
+                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+                if (k != null) {
+                    uid = k;
+                }
+            }
+
+            synchronized (mLock) {
+                SparseArray<Pair<Long, Object>> array = mData.get(uid);
+                if (array == null) {
+                    array = new SparseArray<Pair<Long, Object>>();
+                    mData.put(uid, array);
+                }
+                array.put(pid, new Pair<Long, Object>(System.currentTimeMillis(), extra));
+            }
+        }
+
+        Pair<Long, Object> remove(int pid, int uid) {
+            if (UserHandle.isIsolated(uid)) {
+                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+                if (k != null) {
+                    uid = k;
+                }
+            }
+
+            synchronized (mLock) {
+                SparseArray<Pair<Long, Object>> array = mData.get(uid);
+                if (array != null) {
+                    Pair<Long, Object> p = array.get(pid);
+                    if (p != null) {
+                        array.remove(pid);
+                        return isFresh(p.first) ? p : null;
+                    }
+                }
+            }
+            return null;
+        }
+
+        void removeByUserId(int userId) {
+            if (userId == UserHandle.USER_CURRENT) {
+                userId = mService.mUserController.getCurrentUserId();
+            }
+            synchronized (mLock) {
+                if (userId == UserHandle.USER_ALL) {
+                    mData.clear();
+                    return;
+                }
+                for (int i = mData.size() - 1; i >= 0; i--) {
+                    int uid = mData.keyAt(i);
+                    if (UserHandle.getUserId(uid) == userId) {
+                        mData.removeAt(i);
+                    }
+                }
+            }
+        }
+
+        void removeByUid(int uid, boolean allUsers) {
+            if (UserHandle.isIsolated(uid)) {
+                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+                if (k != null) {
+                    uid = k;
+                }
+            }
+
+            if (allUsers) {
+                uid = UserHandle.getAppId(uid);
+                synchronized (mLock) {
+                    for (int i = mData.size() - 1; i >= 0; i--) {
+                        if (UserHandle.getAppId(mData.keyAt(i)) == uid) {
+                            mData.removeAt(i);
+                        }
+                    }
+                }
+            } else {
+                synchronized (mLock) {
+                    mData.remove(uid);
+                }
+            }
+        }
+
+        void setOnProcDiedListener(BiConsumer<Integer, Integer> listener) {
+            synchronized (mLock) {
+                mProcDiedListener = listener;
+            }
+        }
+
+        void onProcDied(final int pid, final int uid, final Integer status) {
+            if (DEBUG_PROCESSES) {
+                Slog.i(TAG, mTag + ": proc died: pid=" + pid + " uid=" + uid
+                        + ", status=" + status);
+            }
+
+            if (mService == null) {
+                return;
+            }
+
+            // Unlikely but possible: the record has been created
+            // Let's update it if we could find a ApplicationExitInfo record
+            if (!updateExitInfoIfNecessary(pid, uid, status, mPresetReason)) {
+                add(pid, uid, status);
+            }
+
+            // Notify any interesed party regarding the lmkd kills
+            synchronized (mLock) {
+                final BiConsumer<Integer, Integer> listener = mProcDiedListener;
+                if (listener != null) {
+                    mService.mHandler.post(()-> listener.accept(pid, uid));
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index aa8bc04..fa55701 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -16,15 +16,21 @@
 
 package com.android.server.am;
 
+import android.app.ActivityThread;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
+import android.widget.WidgetFlags;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -36,6 +42,19 @@
 final class CoreSettingsObserver extends ContentObserver {
     private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
 
+    private static class DeviceConfigEntry {
+        String namespace;
+        String flag;
+        String coreSettingKey;
+        Class<?> type;
+        DeviceConfigEntry(String namespace, String flag, String coreSettingKey, Class<?> type) {
+            this.namespace = namespace;
+            this.flag = flag;
+            this.coreSettingKey = coreSettingKey;
+            this.type = type;
+        }
+    }
+
     // mapping form property name to its type
     @VisibleForTesting
     static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
@@ -46,6 +65,7 @@
     @VisibleForTesting
     static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<
             String, Class<?>>();
+    static final List<DeviceConfigEntry> sDeviceConfigEntries = new ArrayList<DeviceConfigEntry>();
     static {
         sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
         sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class);
@@ -84,6 +104,11 @@
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLISTS, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class);
         // add other global settings here...
+
+        sDeviceConfigEntries.add(new DeviceConfigEntry(
+                DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ENABLE_CURSOR_CONTROL,
+                WidgetFlags.KEY_ENABLE_CURSOR_CONTROL, boolean.class));
+        // add other device configs here...
     }
 
     private final Bundle mCoreSettings = new Bundle();
@@ -112,6 +137,7 @@
         populateSettings(mCoreSettings, sSecureSettingToTypeMap);
         populateSettings(mCoreSettings, sSystemSettingToTypeMap);
         populateSettings(mCoreSettings, sGlobalSettingToTypeMap);
+        populateSettingsFromDeviceConfig();
         mActivityManagerService.onCoreSettingsChange(mCoreSettings);
     }
 
@@ -133,6 +159,16 @@
             mActivityManagerService.mContext.getContentResolver().registerContentObserver(
                     uri, false, this);
         }
+
+        HashSet<String> deviceConfigNamespaces = new HashSet<>();
+        for (DeviceConfigEntry entry : sDeviceConfigEntries) {
+            if (!deviceConfigNamespaces.contains(entry.namespace)) {
+                DeviceConfig.addOnPropertiesChangedListener(
+                        entry.namespace, ActivityThread.currentApplication().getMainExecutor(),
+                        (DeviceConfig.Properties prop) -> onChange(false));
+                deviceConfigNamespaces.add(entry.namespace);
+            }
+        }
     }
 
     @VisibleForTesting
@@ -164,4 +200,25 @@
             }
         }
     }
+
+    private void populateSettingsFromDeviceConfig() {
+        for (DeviceConfigEntry entry : sDeviceConfigEntries) {
+            if (entry.type == String.class) {
+                mCoreSettings.putString(entry.coreSettingKey,
+                        DeviceConfig.getString(entry.namespace, entry.flag, ""));
+            } else if (entry.type == int.class) {
+                mCoreSettings.putInt(entry.coreSettingKey,
+                        DeviceConfig.getInt(entry.namespace, entry.flag, 0));
+            } else if (entry.type == float.class) {
+                mCoreSettings.putFloat(entry.coreSettingKey,
+                        DeviceConfig.getFloat(entry.namespace, entry.flag, 0));
+            } else if (entry.type == long.class) {
+                mCoreSettings.putLong(entry.coreSettingKey,
+                        DeviceConfig.getLong(entry.namespace, entry.flag, 0));
+            } else if (entry.type == boolean.class) {
+                mCoreSettings.putInt(entry.coreSettingKey,
+                        DeviceConfig.getBoolean(entry.namespace, entry.flag, false) ? 1 : 0);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index f86d6a7..be14b3b 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -17,7 +17,9 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+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.ActivityManager.PROCESS_CAPABILITY_NONE;
 import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
 import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
@@ -33,6 +35,9 @@
 import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
 import static android.app.ActivityManager.PROCESS_STATE_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
 import static android.os.Process.SCHED_OTHER;
 import static android.os.Process.THREAD_GROUP_BACKGROUND;
 import static android.os.Process.THREAD_GROUP_DEFAULT;
@@ -64,6 +69,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 
 import android.app.ActivityManager;
+import android.app.ApplicationExitInfo;
 import android.app.usage.UsageEvents;
 import android.content.Context;
 import android.content.pm.ServiceInfo;
@@ -757,7 +763,10 @@
                             lastCachedGroupUid = lastCachedGroup = 0;
                         }
                         if ((numCached - numCachedExtraGroup) > cachedProcessLimit) {
-                            app.kill("cached #" + numCached, true);
+                            app.kill("cached #" + numCached,
+                                    ApplicationExitInfo.REASON_OTHER,
+                                    ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED,
+                                    true);
                         }
                         break;
                     case PROCESS_STATE_CACHED_EMPTY:
@@ -765,11 +774,17 @@
                                 && app.lastActivityTime < oldTime) {
                             app.kill("empty for "
                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
-                                    / 1000) + "s", true);
+                                    / 1000) + "s",
+                                    ApplicationExitInfo.REASON_OTHER,
+                                    ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
+                                    true);
                         } else {
                             numEmpty++;
                             if (numEmpty > emptyProcessLimit) {
-                                app.kill("empty #" + numEmpty, true);
+                                app.kill("empty #" + numEmpty,
+                                        ApplicationExitInfo.REASON_OTHER,
+                                        ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY,
+                                        true);
                             }
                         }
                         break;
@@ -786,7 +801,7 @@
                     // definition not re-use the same process again, and it is
                     // good to avoid having whatever code was running in them
                     // left sitting around after no longer needed.
-                    app.kill("isolated not needed", true);
+                    app.kill("isolated not needed", ApplicationExitInfo.REASON_OTHER, true);
                 } else {
                     // Keeping this process, update its uid.
                     updateAppUidRecLocked(app);
@@ -1220,10 +1235,6 @@
             }
         }
 
-        if (app.hasLocationForegroundServices()) {
-            capability |= PROCESS_CAPABILITY_FOREGROUND_LOCATION;
-        }
-
         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
                 || procState > PROCESS_STATE_FOREGROUND_SERVICE) {
             if (app.hasForegroundServices()) {
@@ -1387,6 +1398,7 @@
             }
         }
 
+        int capabilityFromFGS = 0; // capability from foreground service.
         for (int is = app.services.size() - 1;
                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
@@ -1435,6 +1447,24 @@
                 }
             }
 
+            if (s.isForeground) {
+                final int fgsType = s.foregroundServiceType;
+                capabilityFromFGS |=
+                        (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION)
+                                != 0 ? PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0;
+                if (s.appInfo.targetSdkVersion < Build.VERSION_CODES.R) {
+                    capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_CAMERA
+                            | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+                } else {
+                    capabilityFromFGS |=
+                            (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA)
+                                    != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA : 0;
+                    capabilityFromFGS |=
+                            (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE)
+                                    != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE : 0;
+                }
+            }
+
             ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
             for (int conni = serviceConnections.size() - 1;
                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
@@ -1895,6 +1925,10 @@
             }
         }
 
+        // apply capability from FGS.
+        if (app.hasForegroundServices()) {
+            capability |= capabilityFromFGS;
+        }
         // TOP process has all capabilities.
         if (procState <= PROCESS_STATE_TOP) {
             capability = PROCESS_CAPABILITY_ALL;
@@ -2032,7 +2066,7 @@
             }
             if (app.waitingToKill != null && app.curReceivers.isEmpty()
                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
-                app.kill(app.waitingToKill, true);
+                app.kill(app.waitingToKill, ApplicationExitInfo.REASON_OTHER, true);
                 success = false;
             } else {
                 int processGroup;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index b7f867d..7f9477ed 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -22,6 +22,7 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
 import static android.os.Process.getFreeMemory;
@@ -53,23 +54,33 @@
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.AppProtoEnums;
+import android.app.ApplicationExitInfo;
+import android.app.ApplicationExitInfo.Reason;
+import android.app.ApplicationExitInfo.SubReason;
 import android.app.IApplicationThread;
+import android.app.IUidObserver;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.res.Resources;
 import android.graphics.Point;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
 import android.os.AppZygote;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.DropBoxManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.StrictMode;
@@ -113,6 +124,7 @@
 import dalvik.system.VMRuntime;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
@@ -282,6 +294,10 @@
     private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
             "persist.device_config.runtime_native.use_app_image_startup_cache";
 
+    // The socket path for zygote to send unsolicited msg.
+    // Must keep sync with com_android_internal_os_Zygote.cpp.
+    private static final String UNSOL_ZYGOTE_MSG_SOCKET_PATH = "/data/system/unsolzygotesocket";
+
     // Low Memory Killer Daemon command codes.
     // These must be kept in sync with lmk_cmd definitions in lmkd.h
     //
@@ -416,12 +432,6 @@
     ActiveUids mActiveUids;
 
     /**
-     * The listener who is intereted with the lmkd kills.
-     */
-    @GuardedBy("mService")
-    private LmkdKillListener mLmkdKillListener = null;
-
-    /**
      * The currently running isolated processes.
      */
     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
@@ -432,6 +442,12 @@
     final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>();
 
     /**
+     * Managees the {@link android.app.ApplicationExitInfo} records.
+     */
+    @GuardedBy("mAppExitInfoTracker")
+    final AppExitInfoTracker mAppExitInfoTracker = new AppExitInfoTracker();
+
+    /**
      * The processes that are forked off an application zygote.
      */
     final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses =
@@ -439,6 +455,28 @@
 
     private PlatformCompat mPlatformCompat = null;
 
+    /**
+     * The server socket in system_server, zygote will connect to it
+     * in order to send unsolicited messages to system_server.
+     */
+    private LocalSocket mSystemServerSocketForZygote;
+
+    /**
+     * Maximum number of bytes that an incoming unsolicited zygote message could be.
+     * To be updated if new message type needs to be supported.
+     */
+    private static final int MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE = 16;
+
+    /**
+     * The buffer to be used to receive the incoming unsolicited zygote message.
+     */
+    private final byte[] mZygoteUnsolicitedMessage = new byte[MAX_ZYGOTE_UNSOLICITED_MESSAGE_SIZE];
+
+    /**
+     * The buffer to be used to receive the SIGCHLD data, it includes pid/uid/status.
+     */
+    private final int[] mZygoteSigChldMessage = new int[3];
+
     interface LmkdKillListener {
         /**
          * Called when there is a process kill by lmkd.
@@ -597,7 +635,6 @@
     final class KillHandler extends Handler {
         static final int KILL_PROCESS_GROUP_MSG = 4000;
         static final int LMKD_RECONNECT_MSG = 4001;
-        static final int LMKD_PROC_KILLED_MSG = 4002;
 
         public KillHandler(Looper looper) {
             super(looper, null, true);
@@ -620,16 +657,17 @@
                                 KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
                     }
                     break;
-                case LMKD_PROC_KILLED_MSG:
-                    handleLmkdProcKilled(msg.arg1 /* pid */, msg.arg2 /* uid */);
-                    break;
-
                 default:
                     super.handleMessage(msg);
             }
         }
     }
 
+    /**
+     * A runner to handle the imperceptible killings.
+     */
+    ImperceptibleKillRunner mImperceptibleKillRunner;
+
     ////////////////////  END FIELDS  ////////////////////
 
     ProcessList() {
@@ -692,9 +730,8 @@
                                     if (receivedLen != 12) {
                                         return false;
                                     }
-                                    sKillHandler.obtainMessage(KillHandler.LMKD_PROC_KILLED_MSG,
-                                            dataReceived.getInt(4), dataReceived.getInt(8))
-                                            .sendToTarget();
+                                    mAppExitInfoTracker.scheduleNoteLmkdProcKilled(
+                                            dataReceived.getInt(4), dataReceived.getInt(8));
                                     return true;
                                 default:
                                     return false;
@@ -702,9 +739,22 @@
                         }
                     }
             );
+            // Start listening on incoming connections from zygotes.
+            mSystemServerSocketForZygote = createSystemServerSocketForZygote();
+            if (mSystemServerSocketForZygote != null) {
+                sKillHandler.getLooper().getQueue().addOnFileDescriptorEventListener(
+                        mSystemServerSocketForZygote.getFileDescriptor(),
+                        EVENT_INPUT, this::handleZygoteMessages);
+            }
+            mAppExitInfoTracker.init(mService, sKillThread.getLooper());
+            mImperceptibleKillRunner = new ImperceptibleKillRunner(sKillThread.getLooper());
         }
     }
 
+    void onSystemReady() {
+        mAppExitInfoTracker.onSystemReady();
+    }
+
     void applyDisplaySize(WindowManagerService wm) {
         if (!mHaveDisplaySize) {
             Point p = new Point();
@@ -1437,7 +1487,10 @@
                             proc.lastCachedPss, holder.appVersion);
                 }
             }
-            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
+            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
+                    ApplicationExitInfo.REASON_OTHER,
+                    ApplicationExitInfo.SUBREASON_LARGE_CACHED,
+                    true);
         } else if (proc != null && !keepIfLarge
                 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
@@ -1456,7 +1509,10 @@
                                 proc.lastCachedPss, holder.appVersion);
                     }
                 }
-                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
+                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached",
+                        ApplicationExitInfo.REASON_OTHER,
+                        ApplicationExitInfo.SUBREASON_LARGE_CACHED,
+                        true);
             }
         }
         return proc;
@@ -2151,6 +2207,9 @@
         if (doKill) {
             // do the killing
             ProcessList.killProcessGroup(app.uid, app.pid);
+            noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                    ApplicationExitInfo.SUBREASON_UNKNOWN,
+                    String.format(formatString, ""));
         }
 
         // wait for the death
@@ -2229,6 +2288,8 @@
             app.pendingStart = false;
             killProcessQuiet(pid);
             Process.killProcessGroup(app.uid, app.pid);
+            noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                    ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
             return false;
         }
         mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
@@ -2314,6 +2375,8 @@
                     if (app.pid > 0) {
                         killProcessQuiet(app.pid);
                         ProcessList.killProcessGroup(app.uid, app.pid);
+                        noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                                ApplicationExitInfo.SUBREASON_UNKNOWN, "hasn't been killed");
                     } else {
                         app.pendingStart = false;
                     }
@@ -2444,6 +2507,12 @@
     @GuardedBy("mService")
     boolean removeProcessLocked(ProcessRecord app,
             boolean callerWillRestart, boolean allowRestart, String reason) {
+        return removeProcessLocked(app, callerWillRestart, allowRestart, reason,
+                ApplicationExitInfo.REASON_OTHER);
+    }
+
+    boolean removeProcessLocked(ProcessRecord app,
+            boolean callerWillRestart, boolean allowRestart, String reason, int reasonCode) {
         final String name = app.processName;
         final int uid = app.uid;
         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
@@ -2479,7 +2548,7 @@
                     needRestart = true;
                 }
             }
-            app.kill(reason, true);
+            app.kill(reason, reasonCode, true);
             mService.handleAppDiedLocked(app, willRestart, allowRestart);
             if (willRestart) {
                 removeLruProcessLocked(app);
@@ -2564,6 +2633,7 @@
                 // the uid of the isolated process is specified by the caller.
                 uid = isolatedUid;
             }
+            mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(uid, info.uid);
             mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
 
             // Register the isolated UID with this application so BatteryStats knows to
@@ -3537,27 +3607,382 @@
         }
     }
 
-    void setLmkdKillListener(final LmkdKillListener listener) {
-        synchronized (mService) {
-            mLmkdKillListener = listener;
+    /**
+     * Create a server socket in system_server, zygote will connect to it
+     * in order to send unsolicited messages to system_server.
+     */
+    private LocalSocket createSystemServerSocketForZygote() {
+        // The file system entity for this socket is created with 0666 perms, owned
+        // by system:system. selinux restricts things so that only zygotes can
+        // access it.
+        final File socketFile = new File(UNSOL_ZYGOTE_MSG_SOCKET_PATH);
+        if (socketFile.exists()) {
+            socketFile.delete();
         }
+
+        LocalSocket serverSocket = null;
+        try {
+            serverSocket = new LocalSocket(LocalSocket.SOCKET_DGRAM);
+            serverSocket.bind(new LocalSocketAddress(
+                    UNSOL_ZYGOTE_MSG_SOCKET_PATH, LocalSocketAddress.Namespace.FILESYSTEM));
+            Os.chmod(UNSOL_ZYGOTE_MSG_SOCKET_PATH, 0666);
+        } catch (Exception e) {
+            if (serverSocket != null) {
+                try {
+                    serverSocket.close();
+                } catch (IOException ex) {
+                }
+                serverSocket = null;
+            }
+        }
+        return serverSocket;
     }
 
-    private void handleLmkdProcKilled(final int pid, final int uid) {
-        // Log only now
+    /**
+     * Handle the unsolicited message from zygote.
+     */
+    private int handleZygoteMessages(FileDescriptor fd, int events) {
+        final int eventFd = fd.getInt$();
+        if ((events & EVENT_INPUT) != 0) {
+            // An incoming message from zygote
+            try {
+                final int len = Os.read(fd, mZygoteUnsolicitedMessage, 0,
+                        mZygoteUnsolicitedMessage.length);
+                if (len > 0 && mZygoteSigChldMessage.length == Zygote.nativeParseSigChld(
+                        mZygoteUnsolicitedMessage, len, mZygoteSigChldMessage)) {
+                    mAppExitInfoTracker.handleZygoteSigChld(
+                            mZygoteSigChldMessage[0] /* pid */,
+                            mZygoteSigChldMessage[1] /* uid */,
+                            mZygoteSigChldMessage[2] /* status */);
+                }
+            } catch (Exception e) {
+                Slog.w(TAG, "Exception in reading unsolicited zygote message: " + e);
+            }
+        }
+        return EVENT_INPUT;
+    }
+
+    /**
+     * Called by ActivityManagerService when a process died.
+     */
+    @GuardedBy("mService")
+    void noteProcessDiedLocked(final ProcessRecord app) {
         if (DEBUG_PROCESSES) {
-            Slog.i(TAG, "lmkd kill: pid=" + pid + " uid=" + uid);
+            Slog.i(TAG, "note: " + app + " died, saving the exit info");
         }
 
-        if (mService == null) {
+        mAppExitInfoTracker.scheduleNoteProcessDiedLocked(app);
+    }
+
+    /**
+     * Called by ActivityManagerService when it decides to kill an application process.
+     */
+    void noteAppKill(final ProcessRecord app, final @Reason int reason,
+            final @SubReason int subReason, final String msg) {
+        if (DEBUG_PROCESSES) {
+            Slog.i(TAG, "note: " + app + " is being killed, reason: " + reason
+                    + ", sub-reason: " + subReason + ", message: " + msg);
+        }
+        mAppExitInfoTracker.scheduleNoteAppKill(app, reason, subReason, msg);
+    }
+
+    void noteAppKill(final int pid, final int uid, final @Reason int reason,
+            final @SubReason int subReason, final String msg) {
+        if (DEBUG_PROCESSES) {
+            Slog.i(TAG, "note: " + pid + " is being killed, reason: " + reason
+                    + ", sub-reason: " + subReason + ", message: " + msg);
+        }
+
+        mAppExitInfoTracker.scheduleNoteAppKill(pid, uid, reason, subReason, msg);
+    }
+
+    /**
+     * Schedule to kill the given pids when the device is idle
+     */
+    void killProcessesWhenImperceptible(int[] pids, String reason, int requester) {
+        if (ArrayUtils.isEmpty(pids)) {
             return;
         }
-        // Notify any interesed party regarding the lmkd kills
+
         synchronized (mService) {
-            final LmkdKillListener listener = mLmkdKillListener;
-            if (listener != null) {
-                mService.mHandler.post(()-> listener.onLmkdKillOccurred(pid, uid));
+            ProcessRecord app;
+            for (int i = 0; i < pids.length; i++) {
+                synchronized (mService.mPidsSelfLocked) {
+                    app = mService.mPidsSelfLocked.get(pids[i]);
+                }
+                if (app != null) {
+                    mImperceptibleKillRunner.enqueueLocked(app, reason, requester);
+                }
             }
         }
     }
+
+    private final class ImperceptibleKillRunner extends IUidObserver.Stub {
+        private static final String EXTRA_PID = "pid";
+        private static final String EXTRA_UID = "uid";
+        private static final String EXTRA_TIMESTAMP = "timestamp";
+        private static final String EXTRA_REASON = "reason";
+        private static final String EXTRA_REQUESTER = "requester";
+
+        private static final String DROPBOX_TAG_IMPERCEPTIBLE_KILL = "imperceptible_app_kill";
+
+        // uid -> killing information mapping
+        private SparseArray<List<Bundle>> mWorkItems = new SparseArray<List<Bundle>>();
+
+        // The last time the various processes have been killed by us.
+        private ProcessMap<Long> mLastProcessKillTimes = new ProcessMap<>();
+
+        // Device idle or not.
+        private volatile boolean mIdle;
+        private boolean mUidObserverEnabled;
+        private Handler mHandler;
+        private IdlenessReceiver mReceiver;
+
+        private final class H extends Handler {
+            static final int MSG_DEVICE_IDLE = 0;
+            static final int MSG_UID_GONE = 1;
+            static final int MSG_UID_STATE_CHANGED = 2;
+
+            H(Looper looper) {
+                super(looper);
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_DEVICE_IDLE:
+                        handleDeviceIdle();
+                        break;
+                    case MSG_UID_GONE:
+                        handleUidGone(msg.arg1 /* uid */);
+                        break;
+                    case MSG_UID_STATE_CHANGED:
+                        handleUidStateChanged(msg.arg1 /* uid */, msg.arg2 /* procState */);
+                        break;
+                }
+            }
+        }
+
+        private final class IdlenessReceiver extends BroadcastReceiver {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final PowerManager pm = mService.mContext.getSystemService(PowerManager.class);
+                switch (intent.getAction()) {
+                    case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:
+                        notifyDeviceIdleness(pm.isLightDeviceIdleMode());
+                        break;
+                    case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
+                        notifyDeviceIdleness(pm.isDeviceIdleMode());
+                        break;
+                }
+            }
+        }
+
+        ImperceptibleKillRunner(Looper looper) {
+            mHandler = new H(looper);
+        }
+
+        @GuardedBy("mService")
+        boolean enqueueLocked(ProcessRecord app, String reason, int requester) {
+            // Throttle the killing request for potential bad app to avoid cpu thrashing
+            Long last = app.isolated ? null : mLastProcessKillTimes.get(app.processName, app.uid);
+            if (last != null && SystemClock.uptimeMillis() < last + MIN_CRASH_INTERVAL) {
+                return false;
+            }
+
+            final Bundle bundle = new Bundle();
+            bundle.putInt(EXTRA_PID, app.pid);
+            bundle.putInt(EXTRA_UID, app.uid);
+            // Since the pid could be reused, let's get the actual start time of each process
+            bundle.putLong(EXTRA_TIMESTAMP, app.startTime);
+            bundle.putString(EXTRA_REASON, reason);
+            bundle.putInt(EXTRA_REQUESTER, requester);
+            List<Bundle> list = mWorkItems.get(app.uid);
+            if (list == null) {
+                list = new ArrayList<Bundle>();
+                mWorkItems.put(app.uid, list);
+            }
+            list.add(bundle);
+            if (mReceiver == null) {
+                mReceiver = new IdlenessReceiver();
+                IntentFilter filter = new IntentFilter(
+                        PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
+                filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+                mService.mContext.registerReceiver(mReceiver, filter);
+            }
+            return true;
+        }
+
+        void notifyDeviceIdleness(boolean idle) {
+            // No lock is held regarding mIdle, this function is the only updater and caller
+            // won't re-entry.
+            boolean diff = mIdle != idle;
+            mIdle = idle;
+            if (diff && idle) {
+                synchronized (this) {
+                    if (mWorkItems.size() > 0) {
+                        mHandler.sendEmptyMessage(H.MSG_DEVICE_IDLE);
+                    }
+                }
+            }
+        }
+
+        private void handleDeviceIdle() {
+            final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
+            final boolean logToDropbox = dbox != null
+                    && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
+
+            synchronized (mService) {
+                final int size = mWorkItems.size();
+                for (int i = size - 1; mIdle && i >= 0; i--) {
+                    List<Bundle> list = mWorkItems.valueAt(i);
+                    final int len = list.size();
+                    for (int j = len - 1; mIdle && j >= 0; j--) {
+                        Bundle bundle = list.get(j);
+                        if (killProcessLocked(
+                                bundle.getInt(EXTRA_PID),
+                                bundle.getInt(EXTRA_UID),
+                                bundle.getLong(EXTRA_TIMESTAMP),
+                                bundle.getString(EXTRA_REASON),
+                                bundle.getInt(EXTRA_REQUESTER),
+                                dbox, logToDropbox)) {
+                            list.remove(j);
+                        }
+                    }
+                    if (list.size() == 0) {
+                        mWorkItems.removeAt(i);
+                    }
+                }
+                registerUidObserverIfNecessaryLocked();
+            }
+        }
+
+        @GuardedBy("mService")
+        private void registerUidObserverIfNecessaryLocked() {
+            // If there are still works remaining, register UID observer
+            if (!mUidObserverEnabled && mWorkItems.size() > 0) {
+                mUidObserverEnabled = true;
+                mService.registerUidObserver(this,
+                        ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
+                        ActivityManager.PROCESS_STATE_UNKNOWN, "android");
+            } else if (mUidObserverEnabled && mWorkItems.size() == 0) {
+                mUidObserverEnabled = false;
+                mService.unregisterUidObserver(this);
+            }
+        }
+
+        /**
+         * Kill the given processes, if they are not exempted.
+         *
+         * @return True if the process is killed, or it's gone already, or we are not allowed to
+         *         kill it (one of the packages in this process is being exempted).
+         */
+        @GuardedBy("mService")
+        private boolean killProcessLocked(final int pid, final int uid, final long timestamp,
+                final String reason, final int requester, final DropBoxManager dbox,
+                final boolean logToDropbox) {
+            ProcessRecord app = null;
+            synchronized (mService.mPidsSelfLocked) {
+                app = mService.mPidsSelfLocked.get(pid);
+            }
+
+            if (app == null || app.pid != pid || app.uid != uid || app.startTime != timestamp) {
+                // This process record has been reused for another process, meaning the old process
+                // has been gone.
+                return true;
+            }
+
+            final int pkgSize = app.pkgList.size();
+            for (int ip = 0; ip < pkgSize; ip++) {
+                if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.contains(
+                        app.pkgList.keyAt(ip))) {
+                    // One of the packages in this process is exempted
+                    return true;
+                }
+            }
+
+            if (mService.mConstants.IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(
+                    app.getReportedProcState())) {
+                // We need to reschedule it.
+                return false;
+            }
+
+            app.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
+
+            if (!app.isolated) {
+                mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
+            }
+
+            if (logToDropbox) {
+                final long now = SystemClock.elapsedRealtime();
+                final StringBuilder sb = new StringBuilder();
+                mService.appendDropBoxProcessHeaders(app, app.processName, sb);
+                sb.append("Reason: " + reason).append("\n");
+                sb.append("Requester UID: " + requester).append("\n");
+                dbox.addText(DROPBOX_TAG_IMPERCEPTIBLE_KILL, sb.toString());
+            }
+            return true;
+        }
+
+        private void handleUidStateChanged(int uid, int procState) {
+            final DropBoxManager dbox = mService.mContext.getSystemService(DropBoxManager.class);
+            final boolean logToDropbox = dbox != null
+                    && dbox.isTagEnabled(DROPBOX_TAG_IMPERCEPTIBLE_KILL);
+            synchronized (mService) {
+                if (mIdle && !mService.mConstants
+                        .IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES.contains(procState)) {
+                    List<Bundle> list = mWorkItems.get(uid);
+                    if (list != null) {
+                        final int len = list.size();
+                        for (int j = len - 1; mIdle && j >= 0; j--) {
+                            Bundle bundle = list.get(j);
+                            if (killProcessLocked(
+                                    bundle.getInt(EXTRA_PID),
+                                    bundle.getInt(EXTRA_UID),
+                                    bundle.getLong(EXTRA_TIMESTAMP),
+                                    bundle.getString(EXTRA_REASON),
+                                    bundle.getInt(EXTRA_REQUESTER),
+                                    dbox, logToDropbox)) {
+                                list.remove(j);
+                            }
+                        }
+                        if (list.size() == 0) {
+                            mWorkItems.remove(uid);
+                        }
+                        registerUidObserverIfNecessaryLocked();
+                    }
+                }
+            }
+        }
+
+        private void handleUidGone(int uid) {
+            synchronized (mService) {
+                mWorkItems.remove(uid);
+                registerUidObserverIfNecessaryLocked();
+            }
+        }
+
+        @Override
+        public void onUidGone(int uid, boolean disabled) {
+            mHandler.obtainMessage(H.MSG_UID_GONE, uid, 0).sendToTarget();
+        }
+
+        @Override
+        public void onUidActive(int uid) {
+        }
+
+        @Override
+        public void onUidIdle(int uid, boolean disabled) {
+        }
+
+        @Override
+        public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
+            mHandler.obtainMessage(H.MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
+        }
+
+        @Override
+        public void onUidCachedChanged(int uid, boolean cached) {
+        }
+    };
 }
+
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 1fef353..0639db0 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -27,6 +27,9 @@
 
 import android.app.ActivityManager;
 import android.app.ApplicationErrorReport;
+import android.app.ApplicationExitInfo;
+import android.app.ApplicationExitInfo.Reason;
+import android.app.ApplicationExitInfo.SubReason;
 import android.app.Dialog;
 import android.app.IApplicationThread;
 import android.content.ComponentName;
@@ -62,8 +65,6 @@
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.Zygote;
-import com.android.server.LocalServices;
-import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowProcessController;
 import com.android.server.wm.WindowProcessListener;
 
@@ -776,7 +777,8 @@
                 } catch (RemoteException e) {
                     // If it's already dead our work is done. If it's wedged just kill it.
                     // We won't get the crash dialog or the error reporting.
-                    kill("scheduleCrash for '" + message + "' failed", true);
+                    kill("scheduleCrash for '" + message + "' failed",
+                            ApplicationExitInfo.REASON_CRASH, true);
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
@@ -784,7 +786,11 @@
         }
     }
 
-    void kill(String reason, boolean noisy) {
+    void kill(String reason, @Reason int reasonCode, boolean noisy) {
+        kill(reason, reasonCode, ApplicationExitInfo.SUBREASON_UNKNOWN, noisy);
+    }
+
+    void kill(String reason, @Reason int reasonCode, @SubReason int subReason, boolean noisy) {
         if (!killedByAm) {
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
             if (mService != null && (noisy || info.uid == mService.mCurOomAdjUid)) {
@@ -793,6 +799,7 @@
                         info.uid);
             }
             if (pid > 0) {
+                mService.mProcessList.noteAppKill(this, reasonCode, subReason, reason);
                 EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
                 Process.killProcessQuiet(pid);
                 ProcessList.killProcessGroup(uid, pid);
@@ -1374,9 +1381,9 @@
     }
 
     @Override
-    public void appDied() {
+    public void appDied(String reason) {
         synchronized (mService) {
-            mService.appDiedLocked(this);
+            mService.appDiedLocked(this, reason);
         }
     }
 
@@ -1441,7 +1448,8 @@
         ArrayList<Integer> firstPids = new ArrayList<>(5);
         SparseArray<Boolean> lastPids = new SparseArray<>(20);
 
-        mWindowProcessController.appEarlyNotResponding(annotation, () -> kill("anr", true));
+        mWindowProcessController.appEarlyNotResponding(annotation, () -> kill("anr",
+                  ApplicationExitInfo.REASON_ANR, true));
 
         long anrTime = SystemClock.uptimeMillis();
         if (isMonitorCpuUsage()) {
@@ -1592,7 +1600,8 @@
         mService.addErrorToDropBox("anr", this, processName, activityShortComponentName,
                 parentShortComponentName, parentPr, annotation, cpuInfo, tracesFile, null);
 
-        if (mWindowProcessController.appNotResponding(info.toString(), () -> kill("anr", true),
+        if (mWindowProcessController.appNotResponding(info.toString(), () -> kill("anr",
+                ApplicationExitInfo.REASON_ANR, true),
                 () -> {
                     synchronized (mService) {
                         mService.mServices.scheduleServiceTimeoutLocked(this);
@@ -1609,7 +1618,7 @@
             }
 
             if (isSilentAnr() && !isDebugging()) {
-                kill("bg anr", true);
+                kill("bg anr", ApplicationExitInfo.REASON_ANR, true);
                 return;
             }
 
@@ -1793,9 +1802,6 @@
         /** current wait for debugger dialog */
         private AppWaitingForDebuggerDialog mWaitDialog;
 
-        private final WindowManagerInternal mWmInternal =
-                LocalServices.getService(WindowManagerInternal.class);
-
         boolean hasCrashDialogs() {
             return mCrashDialogs != null;
         }
@@ -1921,7 +1927,9 @@
             }
             // If there is no foreground window display, fallback to last used display.
             if (displayContexts.isEmpty() || lastUsedOnly) {
-                displayContexts.add(mWmInternal.getTopFocusedDisplayUiContext());
+                displayContexts.add(mService.mWmInternal != null
+                        ? mService.mWmInternal.getTopFocusedDisplayUiContext()
+                        : mService.mUiContext);
             }
             return displayContexts;
         }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index e3b761e..08136a3 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -16,7 +16,9 @@
 
 package com.android.server.appop;
 
+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.FILTER_BY_FEATURE_ID;
 import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
 import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
@@ -467,6 +469,12 @@
                         case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION:
                             return ((capability & PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0)
                                 ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
+                        case OP_CAMERA:
+                            return ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0)
+                                    ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
+                        case OP_RECORD_AUDIO:
+                            return ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0)
+                                    ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
                         default:
                             return AppOpsManager.MODE_ALLOWED;
                     }
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index dfc0080..4bf606e 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -53,6 +53,7 @@
     public OverrideAllowedState getOverrideAllowedState(long changeId, String packageName) {
         boolean debuggableBuild = false;
         boolean finalBuild = false;
+        int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId);
 
         debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild();
         finalBuild = mAndroidBuildClassifier.isFinalBuild();
@@ -76,15 +77,14 @@
         if ((applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
             return new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1);
         }
-        int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId);
-        // Do not allow overriding non-target sdk gated changes on user builds
-        if (minTargetSdk == -1) {
-            return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk);
-        }
         // Allow overriding any change for debuggable apps on non-final builds.
         if (!finalBuild) {
             return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk);
         }
+        // Do not allow overriding non-target sdk gated changes on user builds
+        if (minTargetSdk == -1) {
+            return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk);
+        }
         // Only allow to opt-in for a targetSdk gated change.
         if (applicationInfo.targetSdkVersion < minTargetSdk) {
             return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 1d2a905..0c9abae 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -848,7 +848,11 @@
     }
 
     public int getNetId() {
-        return mNetworkAgent != null ? mNetworkAgent.network.netId : NETID_UNSET;
+        final NetworkAgent agent = mNetworkAgent;
+        if (null == agent) return NETID_UNSET;
+        final Network network = agent.getNetwork();
+        if (null == network) return NETID_UNSET;
+        return network.netId;
     }
 
     private LinkProperties makeLinkProperties() {
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index bc7307b..74c1e63 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.content;
 
+import static android.content.PermissionChecker.PERMISSION_GRANTED;
+
 import android.Manifest;
 import android.accounts.Account;
 import android.annotation.Nullable;
@@ -1212,7 +1214,7 @@
     @RequiresPermission(android.Manifest.permission.CACHE_CONTENT)
     public void putCache(String packageName, Uri key, Bundle value, int userId) {
         Bundle.setDefusable(value, true);
-        enforceCrossUserPermission(userId, TAG);
+        enforceNonFullCrossUserPermission(userId, TAG);
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG);
         mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
                 packageName);
@@ -1234,7 +1236,7 @@
     @Override
     @RequiresPermission(android.Manifest.permission.CACHE_CONTENT)
     public Bundle getCache(String packageName, Uri key, int userId) {
-        enforceCrossUserPermission(userId, TAG);
+        enforceNonFullCrossUserPermission(userId, TAG);
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG);
         mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
                 packageName);
@@ -1302,6 +1304,30 @@
         }
     }
 
+    /**
+     * Checks if the request is from the system or an app that has {@code INTERACT_ACROSS_USERS} or
+     * {@code INTERACT_ACROSS_USERS_FULL} permission, if the {@code userHandle} is not for the
+     * caller.
+     *
+     * @param userHandle the user handle of the user we want to act on behalf of.
+     * @param message the message to log on security exception.
+     */
+    private void enforceNonFullCrossUserPermission(int userHandle, String message) {
+        final int callingUser = UserHandle.getCallingUserId();
+        if (callingUser == userHandle) {
+            return;
+        }
+
+        int interactAcrossUsersState = mContext.checkCallingOrSelfPermission(
+                Manifest.permission.INTERACT_ACROSS_USERS);
+        if (interactAcrossUsersState == PERMISSION_GRANTED) {
+            return;
+        }
+
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
+    }
+
     private static int normalizeSyncable(int syncable) {
         if (syncable > 0) {
             return SyncStorageEngine.AuthorityInfo.SYNCABLE;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index e39d6d5..71ade62 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -39,6 +39,7 @@
 import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.database.ContentObserver;
 import android.graphics.ColorSpace;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -60,6 +61,7 @@
 import android.hardware.input.InputManagerInternal;
 import android.media.projection.IMediaProjection;
 import android.media.projection.IMediaProjectionManager;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -77,6 +79,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.IntArray;
 import android.util.Pair;
@@ -304,6 +307,13 @@
 
     private SensorManager mSensorManager;
 
+    // Whether minimal post processing is allowed by the user.
+    @GuardedBy("mSyncRoot")
+    private boolean mMinimalPostProcessingAllowed;
+
+    // Receives notifications about changes to Settings.
+    private SettingsObserver mSettingsObserver;
+
     public DisplayManagerService(Context context) {
         this(context, new Injector());
     }
@@ -403,6 +413,7 @@
                 BrightnessConfiguration config =
                         mPersistentDataStore.getBrightnessConfiguration(userSerial);
                 mDisplayPowerController.setBrightnessConfiguration(config);
+                handleSettingsChange();
             }
             mDisplayPowerController.onSwitchUser(newUserId);
         }
@@ -428,6 +439,8 @@
             // Just in case the top inset changed before the system was ready. At this point, any
             // relevant configuration should be in place.
             recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
+
+            updateSettingsLocked();
         }
 
         mDisplayModeDirector.setDesiredDisplayModeSpecsListener(
@@ -435,6 +448,8 @@
         mDisplayModeDirector.start(mSensorManager);
 
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
+
+        mSettingsObserver = new SettingsObserver();
     }
 
     @VisibleForTesting
@@ -569,6 +584,33 @@
         }
     }
 
+    private class SettingsObserver extends ContentObserver {
+        SettingsObserver() {
+            super(mHandler);
+
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Secure.getUriFor(
+                        Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED), false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            handleSettingsChange();
+        }
+    }
+
+    private void handleSettingsChange() {
+        synchronized (mSyncRoot) {
+            updateSettingsLocked();
+            scheduleTraversalLocked(false);
+        }
+    }
+
+    private void updateSettingsLocked() {
+        mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0;
+    }
+
     private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
         synchronized (mSyncRoot) {
             LogicalDisplay display = mLogicalDisplays.get(displayId);
@@ -1192,7 +1234,7 @@
     }
 
     private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
-            float requestedRefreshRate, int requestedModeId, boolean requestedMinimalPostProcessing,
+            float requestedRefreshRate, int requestedModeId, boolean preferMinimalPostProcessing,
             boolean inTraversal) {
         synchronized (mSyncRoot) {
             LogicalDisplay display = mLogicalDisplays.get(displayId);
@@ -1220,14 +1262,13 @@
             mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode(
                     displayId, requestedModeId);
 
+            if (display.getDisplayInfoLocked().minimalPostProcessingSupported) {
+                boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing;
 
-            if (display.getDisplayInfoLocked().minimalPostProcessingSupported
-                    && (display.getRequestedMinimalPostProcessingLocked()
-                    != requestedMinimalPostProcessing)) {
-
-                display.setRequestedMinimalPostProcessingLocked(requestedMinimalPostProcessing);
-
-                shouldScheduleTraversal = true;
+                if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) {
+                    display.setRequestedMinimalPostProcessingLocked(mppRequest);
+                    shouldScheduleTraversal = true;
+                }
             }
 
             if (shouldScheduleTraversal) {
@@ -1305,13 +1346,21 @@
     }
 
     private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) {
-        final IBinder token = getDisplayToken(displayId);
-        if (token == null) {
-            return null;
+        synchronized (mSyncRoot) {
+            final IBinder token = getDisplayToken(displayId);
+            if (token == null) {
+                return null;
+            }
+            final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId);
+            if (logicalDisplay == null) {
+                return null;
+            }
+
+            final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
+            return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(),
+                    displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(),
+                    false /* useIdentityTransform */, 0 /* rotation */);
         }
-        return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
-                        token, new Rect(), 0 /* width */, 0 /* height */,
-                        false /* useIdentityTransform */, 0 /* rotation */);
     }
 
     @VisibleForTesting
@@ -2244,6 +2293,13 @@
         }
 
         @Override // Binder call
+        public boolean isMinimalPostProcessingRequested(int displayId) {
+            synchronized (mSyncRoot) {
+                return mLogicalDisplays.get(displayId).getRequestedMinimalPostProcessingLocked();
+            }
+        }
+
+        @Override // Binder call
         public void setTemporaryBrightness(int brightness) {
             mContext.enforceCallingOrSelfPermission(
                     Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 7233f34..baae4ea 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1622,7 +1622,7 @@
         }
 
         if (credential.isNone()) {
-            clearUserKeyProtection(userId);
+            clearUserKeyProtection(userId, null);
             gateKeeperClearSecureUserId(userId);
             mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
             // Still update PASSWORD_TYPE_KEY if we are running in pre-synthetic password code path,
@@ -1813,9 +1813,17 @@
         addUserKeyAuth(userId, token, secretFromCredential(credential));
     }
 
-    private void clearUserKeyProtection(int userId) {
+    private void clearUserKeyProtection(int userId, byte[] secret) {
         if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
-        addUserKeyAuth(userId, null, null);
+        final UserInfo userInfo = mUserManager.getUserInfo(userId);
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            mStorageManager.clearUserKeyAuth(userId, userInfo.serialNumber, null, secret);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("clearUserKeyAuth failed user=" + userId);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
     }
 
     private static byte[] secretFromCredential(LockscreenCredential credential) {
@@ -2571,7 +2579,7 @@
             setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
             setKeystorePassword(auth.deriveKeyStorePassword(), userId);
         } else {
-            clearUserKeyProtection(userId);
+            clearUserKeyProtection(userId, null);
             setKeystorePassword(null, userId);
             gateKeeperClearSecureUserId(userId);
         }
@@ -2765,7 +2773,7 @@
             // during boot. Vold storage needs to be unlocked before manipulation of the keys can
             // succeed.
             unlockUserKey(userId, null, auth.deriveDiskEncryptionKey());
-            clearUserKeyProtection(userId);
+            clearUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
             fixateNewestUserKeyAuth(userId);
             unlockKeystore(auth.deriveKeyStorePassword(), userId);
             setKeystorePassword(null, userId);
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index b67335a..837c489 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -17,6 +17,7 @@
 package com.android.server.media;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -58,6 +59,7 @@
     private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
     private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener();
 
+    // TODO: The mActiveDevice should be set when BluetoothRouteProvider is created.
     private BluetoothDevice mActiveDevice = null;
 
     static synchronized BluetoothRouteProvider getInstance(@NonNull Context context,
@@ -125,6 +127,14 @@
         return routes;
     }
 
+    @Nullable String getActiveDeviceAddress() {
+        BluetoothDevice device = mActiveDevice;
+        if (device == null) {
+            return null;
+        }
+        return device.getAddress();
+    }
+
     private void notifyBluetoothRoutesUpdated() {
         if (mListener != null) {
             mListener.onBluetoothRoutesUpdated(getBluetoothRoutes());
@@ -135,7 +145,7 @@
         BluetoothRouteInfo newBtRoute = new BluetoothRouteInfo();
         newBtRoute.btDevice = device;
         newBtRoute.route = new MediaRoute2Info.Builder(device.getAddress(), device.getName())
-                .addFeature(SystemMediaRoute2Provider.TYPE_LIVE_AUDIO)
+                .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
                 .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
                 .setDescription(mContext.getResources().getText(
                         R.string.bluetooth_a2dp_audio_route_name).toString())
@@ -281,8 +291,8 @@
                             setRouteConnectionStateForDevice(device,
                                     MediaRoute2Info.CONNECTION_STATE_CONNECTED);
                         }
-                        notifyBluetoothRoutesUpdated();
                         mActiveDevice = device;
+                        notifyBluetoothRoutesUpdated();
                     }
                     break;
                 case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 2167530..f9169ee6 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -112,6 +112,30 @@
         }
     }
 
+    @NonNull
+    public RoutingSessionInfo getSystemSessionInfo() {
+        final int uid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            RoutingSessionInfo systemSessionInfo = null;
+            synchronized (mLock) {
+                UserRecord userRecord = getOrCreateUserRecordLocked(userId);
+                List<RoutingSessionInfo> sessionInfos =
+                        userRecord.mHandler.mSystemProvider.getSessionInfos();
+                if (sessionInfos != null && !sessionInfos.isEmpty()) {
+                    systemSessionInfo = sessionInfos.get(0);
+                } else {
+                    Slog.w(TAG, "System provider does not have any session info.");
+                }
+            }
+            return systemSessionInfo;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     public void registerClient(@NonNull IMediaRouter2Client client,
             @NonNull String packageName) {
         Objects.requireNonNull(client, "client must not be null");
@@ -1351,6 +1375,16 @@
             List<IMediaRouter2Manager> managers = getManagers();
             notifySessionInfosChangedToManagers(managers);
 
+            // For system provider, notify all clients.
+            if (provider == mSystemProvider) {
+                MediaRouter2ServiceImpl service = mServiceRef.get();
+                if (service == null) {
+                    return;
+                }
+                notifySessionInfoChangedToClients(getClients(), sessionInfo);
+                return;
+            }
+
             Client2Record client2Record = mSessionToClientMap.get(
                     sessionInfo.getId());
             if (client2Record == null) {
@@ -1509,6 +1543,17 @@
             }
         }
 
+        private void notifySessionInfoChangedToClients(List<IMediaRouter2Client> clients,
+                RoutingSessionInfo sessionInfo) {
+            for (IMediaRouter2Client client : clients) {
+                try {
+                    client.notifySessionInfoChanged(sessionInfo);
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to notify session info changed. Client probably died.", ex);
+                }
+            }
+        }
+
         private void notifyRoutesToManager(IMediaRouter2Manager manager) {
             List<MediaRoute2Info> routes = new ArrayList<>();
             for (MediaRoute2ProviderInfo providerInfo : mLastProviderInfos) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 5437fad..e1d3803 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -444,6 +444,12 @@
 
     // Binder call
     @Override
+    public RoutingSessionInfo getSystemSessionInfo() {
+        return mService2.getSystemSessionInfo();
+    }
+
+    // Binder call
+    @Override
     public void registerClient2(IMediaRouter2Client client, String packageName) {
         final int uid = Binder.getCallingUid();
         if (!validatePackageName(uid, packageName)) {
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 56c33fe..6f6d8a1 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -16,6 +16,9 @@
 
 package com.android.server.media;
 
+import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
+import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO;
+
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
@@ -26,17 +29,20 @@
 import android.media.IAudioService;
 import android.media.MediaRoute2Info;
 import android.media.MediaRoute2ProviderInfo;
+import android.media.RoutingSessionInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.R;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers.
@@ -46,11 +52,7 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
-    static final String BLUETOOTH_ROUTE_ID = "BLUETOOTH_ROUTE";
-
-    // TODO: Move these to a proper place
-    public static final String TYPE_LIVE_AUDIO = "android.media.intent.route.TYPE_LIVE_AUDIO";
-    public static final String TYPE_LIVE_VIDEO = "android.media.intent.route.TYPE_LIVE_VIDEO";
+    static final String SYSTEM_SESSION_ID = "SYSTEM_SESSION";
 
     private final AudioManager mAudioManager;
     private final IAudioService mAudioService;
@@ -92,6 +94,14 @@
         mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> {
             mBluetoothRoutes = routes;
             publishRoutes();
+
+            boolean sessionInfoChanged;
+            synchronized (mLock) {
+                sessionInfoChanged = updateSessionInfosIfNeededLocked();
+            }
+            if (sessionInfoChanged) {
+                notifySessionInfoUpdated();
+            }
         });
         initializeRoutes();
     }
@@ -147,8 +157,8 @@
                         : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
                 .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
                 .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
-                .addFeature(TYPE_LIVE_AUDIO)
-                .addFeature(TYPE_LIVE_VIDEO)
+                .addFeature(FEATURE_LIVE_AUDIO)
+                .addFeature(FEATURE_LIVE_VIDEO)
                 .build();
 
         AudioRoutesInfo newAudioRoutes = null;
@@ -172,6 +182,9 @@
         }
         setProviderState(builder.build());
         mHandler.post(() -> notifyProviderState());
+
+        // Note: No lock needed when initializing.
+        updateSessionInfosIfNeededLocked();
     }
 
     void updateAudioRoutes(AudioRoutesInfo newRoutes) {
@@ -195,14 +208,43 @@
                         : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
                 .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
                 .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
-                .addFeature(TYPE_LIVE_AUDIO)
-                .addFeature(TYPE_LIVE_VIDEO)
+                .addFeature(FEATURE_LIVE_AUDIO)
+                .addFeature(FEATURE_LIVE_VIDEO)
                 .build();
 
         publishRoutes();
     }
 
     /**
+     * Updates the mSessionInfo. Returns true if the session info is changed.
+     */
+    boolean updateSessionInfosIfNeededLocked() {
+        RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(0);
+
+        RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
+                SYSTEM_SESSION_ID, "" /* clientPackageName */)
+                .setSystemSession(true);
+        String activeBtDeviceAddress = mBtRouteProvider.getActiveDeviceAddress();
+
+        RoutingSessionInfo newSessionInfo;
+        if (!TextUtils.isEmpty(activeBtDeviceAddress)) {
+            // Bluetooth route. Set the route ID with the device's address.
+            newSessionInfo = builder.addSelectedRoute(activeBtDeviceAddress).build();
+        } else {
+            // Default device
+            newSessionInfo = builder.addSelectedRoute(mDefaultRoute.getId()).build();
+        }
+
+        if (Objects.equals(oldSessionInfo, newSessionInfo)) {
+            return false;
+        } else {
+            mSessionInfos.clear();
+            mSessionInfos.add(newSessionInfo);
+            return true;
+        }
+    }
+
+    /**
      * The first route should be the currently selected system route.
      * For example, if there are two system routes (BT and device speaker),
      * BT will be the first route in the list.
@@ -215,4 +257,12 @@
         }
         setAndNotifyProviderState(builder.build());
     }
+
+    void notifySessionInfoUpdated() {
+        RoutingSessionInfo sessionInfo;
+        synchronized (mLock) {
+            sessionInfo = mSessionInfos.get(0);
+        }
+        mCallback.onSessionUpdated(this, sessionInfo);
+    }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c518614..bb954ab 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -169,6 +169,7 @@
 import android.os.Binder;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.HandlerThread;
 import android.os.IDeviceIdleController;
 import android.os.INetworkManagementService;
@@ -882,7 +883,8 @@
 
             // Listen for subscriber changes
             mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
-                    new OnSubscriptionsChangedListener(mHandler.getLooper()) {
+                    new HandlerExecutor(mHandler),
+                    new OnSubscriptionsChangedListener() {
                         @Override
                         public void onSubscriptionsChanged() {
                             updateNetworksInternal();
diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
index eaf120e..0e14364 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
@@ -15,7 +15,10 @@
 */
 package com.android.server.notification;
 
+import android.app.Notification;
+import android.app.NotificationChannel;
 import android.content.Context;
+import android.util.FeatureFlagUtils;
 import android.util.Slog;
 
 /**
@@ -26,8 +29,10 @@
     private static final boolean DBG = false;
 
     private RankingConfig mConfig;
+    private Context mContext;
 
     public void initialize(Context ctx, NotificationUsageStats usageStats) {
+        mContext = ctx;
         if (DBG) Slog.d(TAG, "Initializing  " + getClass().getSimpleName() + ".");
     }
 
@@ -41,11 +46,11 @@
             if (DBG) Slog.d(TAG, "missing config");
             return null;
         }
-
-        record.updateNotificationChannel(mConfig.getConversationNotificationChannel(
+        NotificationChannel updatedChannel = mConfig.getConversationNotificationChannel(
                 record.sbn.getPackageName(),
                 record.sbn.getUid(), record.getChannel().getId(),
-                record.getNotification().getShortcutId(), true, false));
+                record.sbn.getShortcutId(mContext), true, false);
+        record.updateNotificationChannel(updatedChannel);
 
         return null;
     }
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index 2247e54..e8cb163 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -62,7 +62,7 @@
 
     private static final String TAG = "NotiHistoryDatabase";
     private static final boolean DEBUG = NotificationManagerService.DBG;
-    private static final int HISTORY_RETENTION_DAYS = 2;
+    private static final int HISTORY_RETENTION_DAYS = 1;
     private static final int HISTORY_RETENTION_MS = 24 * 60 * 60 * 1000;
     private static final long WRITE_BUFFER_INTERVAL_MS = 1000 * 60 * 20;
 
@@ -172,7 +172,7 @@
 
     public void addNotification(final HistoricalNotification notification) {
         synchronized (mLock) {
-            mBuffer.addNotificationToWrite(notification);
+            mBuffer.addNewNotificationToWrite(notification);
             // Each time we have new history to write to disk, schedule a write in [interval] ms
             if (mBuffer.getHistoryCount() == 1) {
                 mFileWriteHandler.postDelayed(mWriteBufferRunnable, WRITE_BUFFER_INTERVAL_MS);
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryManager.java b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
index 1b56c7b..41bc29f 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryManager.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryManager.java
@@ -68,6 +68,8 @@
     private final SparseArray<List<String>> mUserPendingPackageRemovals = new SparseArray<>();
     @GuardedBy("mLock")
     private final SparseBooleanArray mHistoryEnabled = new SparseBooleanArray();
+    @GuardedBy("mLock")
+    private final SparseBooleanArray mUserPendingHistoryDisables = new SparseBooleanArray();
 
     public NotificationHistoryManager(Context context, Handler handler) {
         mContext = context;
@@ -75,6 +77,11 @@
         mSettingsObserver = new SettingsObserver(handler);
     }
 
+    @VisibleForTesting
+    void onDestroy() {
+        mSettingsObserver.stopObserving();
+    }
+
     void onBootPhaseAppsCanStart() {
         mSettingsObserver.observe();
     }
@@ -99,8 +106,8 @@
             }
 
             // delete history if it was disabled when the user was locked
-            if (!mHistoryEnabled.get(userId)) {
-                userHistory.disableHistory();
+            if (mUserPendingHistoryDisables.get(userId)) {
+                disableHistory(userHistory, userId);
             }
         }
     }
@@ -118,6 +125,7 @@
             // removed) - we just need clean up our internal state for GC
             mUserPendingPackageRemovals.put(userId, null);
             mHistoryEnabled.put(userId, false);
+            mUserPendingHistoryDisables.put(userId, false);
             onUserStopped(userId);
         }
     }
@@ -213,20 +221,29 @@
 
     void onHistoryEnabledChanged(@UserIdInt int userId, boolean historyEnabled) {
         synchronized (mLock) {
-            mHistoryEnabled.put(userId, historyEnabled);
-
-            // These requests might fail if the user is locked; onUserUnlocked will pick up those
-            // cases
+            if (historyEnabled) {
+                mHistoryEnabled.put(userId, historyEnabled);
+            }
             final NotificationHistoryDatabase userHistory =
                     getUserHistoryAndInitializeIfNeededLocked(userId);
             if (userHistory != null) {
                 if (!historyEnabled) {
-                    userHistory.disableHistory();
+                    disableHistory(userHistory, userId);
                 }
+            } else {
+                mUserPendingHistoryDisables.put(userId, !historyEnabled);
             }
         }
     }
 
+    private void disableHistory(NotificationHistoryDatabase userHistory, @UserIdInt int userId) {
+        userHistory.disableHistory();
+
+        mUserPendingHistoryDisables.put(userId, false);
+        mHistoryEnabled.put(userId, false);
+        mUserState.put(userId, null);
+    }
+
     @GuardedBy("mLock")
     private @Nullable NotificationHistoryDatabase getUserHistoryAndInitializeIfNeededLocked(
             int userId) {
@@ -316,6 +333,11 @@
             }
         }
 
+        void stopObserving() {
+            ContentResolver resolver = mContext.getContentResolver();
+            resolver.unregisterContentObserver(this);
+        }
+
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
             update(uri, userId);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1d49364..385d84a 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -208,6 +208,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.FeatureFlagUtils;
 import android.util.IntArray;
 import android.util.Log;
 import android.util.Pair;
@@ -3038,7 +3039,7 @@
 
         @Override
         public void createConversationNotificationChannelForPackage(String pkg, int uid,
-                NotificationChannel parentChannel, String conversationId) {
+                String triggeringKey, NotificationChannel parentChannel, String conversationId) {
             enforceSystemOrSystemUI("only system can call this");
             Preconditions.checkNotNull(parentChannel);
             Preconditions.checkNotNull(conversationId);
@@ -3049,6 +3050,8 @@
             conversationChannel.setConversationId(parentId, conversationId);
             createNotificationChannelsImpl(
                     pkg, uid, new ParceledListSlice(Arrays.asList(conversationChannel)));
+            mRankingHandler.requestSort();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -5257,9 +5260,10 @@
         if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
             channelId = (new Notification.TvExtender(notification)).getChannelId();
         }
-        // TODO: flag this behavior
         String shortcutId = notification.getShortcutId();
-        if (shortcutId == null
+        if (FeatureFlagUtils.isEnabled(getContext(),
+                FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ)
+            && shortcutId == null
             && notification.getNotificationStyle() == Notification.MessagingStyle.class) {
             shortcutId = id + tag + NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
         }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 185d75c..b0c1863 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 
@@ -40,6 +41,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.FeatureFlagUtils;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
@@ -139,6 +141,8 @@
     private boolean mAreChannelsBypassingDnd;
     private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS;
 
+    private boolean mAllowInvalidShortcuts = false;
+
     private static final String BADGING_FORCED_TRUE = "force_badging_true_for_bug";
 
     // STOPSHIP (b/142218092) this should be removed before ship
@@ -164,6 +168,8 @@
         updateBadgingEnabled();
         updateBubblesEnabled();
         syncChannelsBypassingDnd(mContext.getUserId());
+        mAllowInvalidShortcuts = FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ);
     }
 
     public void readXml(XmlPullParser parser, boolean forRestore, int userId)
@@ -266,7 +272,14 @@
                                         }
                                         channel.setImportanceLockedByCriticalDeviceFunction(
                                                 r.defaultAppLockedImportance);
-                                        r.channels.put(id, channel);
+                                        boolean isInvalidShortcutChannel =
+                                                channel.getConversationId() != null &&
+                                                        channel.getConversationId().contains(
+                                                                PLACEHOLDER_CONVERSATION_ID);
+                                        if (mAllowInvalidShortcuts || (!mAllowInvalidShortcuts
+                                                && !isInvalidShortcutChannel)) {
+                                            r.channels.put(id, channel);
+                                        }
                                     }
                                 }
                                 // Delegate
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index ed71399..bdc1b07 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -16,6 +16,8 @@
 package com.android.server.pm;
 
 import static android.app.AppOpsManager.OP_INTERACT_ACROSS_PROFILES;
+import static android.content.Intent.FLAG_RECEIVER_REGISTERED_ONLY;
+import static android.content.pm.CrossProfileApps.ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 
@@ -26,6 +28,7 @@
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.AppOpsManager.Mode;
 import android.app.IApplicationThread;
 import android.app.admin.DevicePolicyEventLogger;
 import android.app.admin.DevicePolicyManagerInternal;
@@ -66,8 +69,6 @@
     private Context mContext;
     private Injector mInjector;
     private AppOpsService mAppOpsService;
-    private final DevicePolicyManagerInternal mDpmi;
-    private final IPackageManager mIpm;
 
     public CrossProfileAppsServiceImpl(Context context) {
         this(context, new InjectorImpl(context));
@@ -77,8 +78,6 @@
     CrossProfileAppsServiceImpl(Context context, Injector injector) {
         mContext = context;
         mInjector = injector;
-        mIpm = AppGlobals.getPackageManager();
-        mDpmi = LocalServices.getService(DevicePolicyManagerInternal.class);
     }
 
     @Override
@@ -144,7 +143,7 @@
             // must have the required permission and the users must be in the same profile group
             // in order to launch any of its own activities.
             if (callerUserId != userId) {
-                final int permissionFlag = ActivityManager.checkComponentPermission(
+                final int permissionFlag = mInjector.checkComponentPermission(
                         android.Manifest.permission.INTERACT_ACROSS_PROFILES, callingUid,
                         -1, true);
                 if (permissionFlag != PackageManager.PERMISSION_GRANTED
@@ -172,23 +171,27 @@
     public boolean canRequestInteractAcrossProfiles(String callingPackage) {
         Objects.requireNonNull(callingPackage);
         verifyCallingPackage(callingPackage);
-
-        final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(
+        return canRequestInteractAcrossProfilesUnchecked(
                 callingPackage, mInjector.getCallingUserId());
+    }
+
+    private boolean canRequestInteractAcrossProfilesUnchecked(
+            String packageName, @UserIdInt int userId) {
+        List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(packageName, userId);
         if (targetUserProfiles.isEmpty()) {
             return false;
         }
-
         if (!hasRequestedAppOpPermission(
-                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), callingPackage)) {
+                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)) {
             return false;
         }
-        return isCrossProfilePackageWhitelisted(callingPackage);
+        return isCrossProfilePackageWhitelisted(packageName);
     }
 
     private boolean hasRequestedAppOpPermission(String permission, String packageName) {
         try {
-            String[] packages = mIpm.getAppOpPermissionPackages(permission);
+            String[] packages =
+                    mInjector.getIPackageManager().getAppOpPermissionPackages(permission);
             return ArrayUtils.contains(packages, packageName);
         } catch (RemoteException exc) {
             Slog.e(TAG, "PackageManager dead. Cannot get permission info");
@@ -206,7 +209,6 @@
         if (targetUserProfiles.isEmpty()) {
             return false;
         }
-
         final int callingUid = mInjector.getCallingUid();
         return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid)
                 || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid)
@@ -219,7 +221,8 @@
     private boolean isCrossProfilePackageWhitelisted(String packageName) {
         final long ident = mInjector.clearCallingIdentity();
         try {
-            return mDpmi.getAllCrossProfilePackages().contains(packageName);
+            return mInjector.getDevicePolicyManagerInternal()
+                    .getAllCrossProfilePackages().contains(packageName);
         } finally {
             mInjector.restoreCallingIdentity(ident);
         }
@@ -295,6 +298,104 @@
         }
     }
 
+    @Override
+    public void setInteractAcrossProfilesAppOp(String packageName, @Mode int newMode) {
+        final int callingUid = mInjector.getCallingUid();
+        if (!isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid)
+                && !isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid)) {
+            throw new SecurityException(
+                    "INTERACT_ACROSS_USERS or INTERACT_ACROSS_USERS_FULL is required to set the"
+                            + " app-op for interacting across profiles.");
+        }
+        if (!isPermissionGranted(Manifest.permission.MANAGE_APP_OPS_MODES, callingUid)) {
+            throw new SecurityException(
+                    "MANAGE_APP_OPS_MODES is required to set the app-op for interacting across"
+                            + " profiles.");
+        }
+        final int callingUserId = mInjector.getCallingUserId();
+        if (newMode == AppOpsManager.MODE_ALLOWED
+                && !canRequestInteractAcrossProfilesUnchecked(packageName, callingUserId)) {
+            // The user should not be prompted for apps that cannot request to interact across
+            // profiles. However, we return early here if required to avoid race conditions.
+            Slog.e(TAG, "Tried to turn on the appop for interacting across profiles for invalid"
+                    + " app " + packageName);
+            return;
+        }
+        final int[] profileIds =
+                mInjector.getUserManager().getProfileIds(callingUserId, /* enabledOnly= */ false);
+        for (int profileId : profileIds) {
+            if (!isPackageInstalled(packageName, profileId)) {
+                continue;
+            }
+            setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId);
+        }
+    }
+
+    private boolean isPackageInstalled(String packageName, @UserIdInt int userId) {
+        final int callingUid = mInjector.getCallingUid();
+        final long identity = mInjector.clearCallingIdentity();
+        try {
+            final PackageInfo info =
+                    mInjector.getPackageManagerInternal()
+                            .getPackageInfo(
+                                    packageName,
+                                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
+                                    callingUid,
+                                    userId);
+            return info != null;
+        } finally {
+            mInjector.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void setInteractAcrossProfilesAppOpForUser(
+            String packageName, @Mode int newMode, @UserIdInt int userId) {
+        try {
+            setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "Missing package " + packageName + " on user ID " + userId, e);
+        }
+    }
+
+    private void setInteractAcrossProfilesAppOpForUserOrThrow(
+            String packageName, @Mode int newMode, @UserIdInt int userId)
+            throws PackageManager.NameNotFoundException {
+        final int uid = mInjector.getPackageManager()
+                .getPackageUidAsUser(packageName, /* flags= */ 0, userId);
+        if (currentModeEquals(newMode, packageName, uid)) {
+            Slog.w(TAG,"Attempt to set mode to existing value of " + newMode + " for "
+                    + packageName + " on user ID " + userId);
+            return;
+        }
+        mInjector.getAppOpsManager()
+                .setMode(OP_INTERACT_ACROSS_PROFILES,
+                        uid,
+                        packageName,
+                        newMode);
+        sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId));
+    }
+
+    private boolean currentModeEquals(@Mode int otherMode, String packageName, int uid) {
+        final String op =
+                AppOpsManager.permissionToOp(Manifest.permission.INTERACT_ACROSS_PROFILES);
+        return otherMode ==
+                mInjector.getAppOpsManager().unsafeCheckOpNoThrow(op, uid, packageName);
+    }
+
+    private void sendCanInteractAcrossProfilesChangedBroadcast(
+            String packageName, int uid, UserHandle userHandle) {
+        final Intent intent = new Intent(ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED)
+                .setPackage(packageName);
+        if (!appDeclaresCrossProfileAttribute(uid)) {
+            intent.addFlags(FLAG_RECEIVER_REGISTERED_ONLY);
+        }
+        mInjector.sendBroadcastAsUser(intent, userHandle);
+    }
+
+    private boolean appDeclaresCrossProfileAttribute(int uid) {
+        return mInjector.getPackageManagerInternal().getPackage(uid).isCrossProfile();
+    }
+
     private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
         final long ident = mInjector.clearCallingIdentity();
         try {
@@ -311,8 +412,8 @@
         mInjector.getAppOpsManager().checkPackage(mInjector.getCallingUid(), callingPackage);
     }
 
-    private static boolean isPermissionGranted(String permission, int uid) {
-        return PackageManager.PERMISSION_GRANTED == ActivityManager.checkComponentPermission(
+    private boolean isPermissionGranted(String permission, int uid) {
+        return PackageManager.PERMISSION_GRANTED == mInjector.checkComponentPermission(
                 permission, uid, /* owningUid= */-1, /* exported= */ true);
     }
 
@@ -376,6 +477,27 @@
         public ActivityTaskManagerInternal getActivityTaskManagerInternal() {
             return LocalServices.getService(ActivityTaskManagerInternal.class);
         }
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return AppGlobals.getPackageManager();
+        }
+
+        @Override
+        public DevicePolicyManagerInternal getDevicePolicyManagerInternal() {
+            return LocalServices.getService(DevicePolicyManagerInternal.class);
+        }
+
+        @Override
+        public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+            mContext.sendBroadcastAsUser(intent, user);
+        }
+
+        @Override
+        public int checkComponentPermission(
+                String permission, int uid, int owningUid, boolean exported) {
+            return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
+        }
     }
 
     @VisibleForTesting
@@ -401,5 +523,13 @@
         ActivityManagerInternal getActivityManagerInternal();
 
         ActivityTaskManagerInternal getActivityTaskManagerInternal();
+
+        IPackageManager getIPackageManager();
+
+        DevicePolicyManagerInternal getDevicePolicyManagerInternal();
+
+        void sendBroadcastAsUser(Intent intent, UserHandle user);
+
+        int checkComponentPermission(String permission, int uid, int owningUid, boolean exported);
     }
 }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 71555c9..78875da 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -152,7 +152,6 @@
     private static final int MSG_COMMIT = 1;
     private static final int MSG_ON_PACKAGE_INSTALLED = 2;
     private static final int MSG_SEAL = 3;
-    private static final int MSG_TRANSFER = 4;
 
     /** XML constants used for persisting a session */
     static final String TAG_SESSION = "session";
@@ -388,32 +387,19 @@
     private final Handler.Callback mHandlerCallback = new Handler.Callback() {
         @Override
         public boolean handleMessage(Message msg) {
-            SomeArgs args;
-            String packageName;
-            IntentSender statusReceiver;
             switch (msg.what) {
                 case MSG_SEAL:
-                    statusReceiver = (IntentSender) msg.obj;
-
-                    handleSeal(statusReceiver);
+                    handleSeal((IntentSender) msg.obj);
                     break;
                 case MSG_COMMIT:
                     handleCommit();
                     break;
-                case MSG_TRANSFER:
-                    args = (SomeArgs) msg.obj;
-                    packageName = (String) args.arg1;
-                    statusReceiver = (IntentSender) args.arg2;
-                    args.recycle();
-
-                    handleTransfer(statusReceiver, packageName);
-                    break;
                 case MSG_ON_PACKAGE_INSTALLED:
-                    args = (SomeArgs) msg.obj;
-                    packageName = (String) args.arg1;
+                    final SomeArgs args = (SomeArgs) msg.obj;
+                    final String packageName = (String) args.arg1;
                     final String message = (String) args.arg2;
                     final Bundle extras = (Bundle) args.arg3;
-                    statusReceiver = (IntentSender) args.arg4;
+                    final IntentSender statusReceiver = (IntentSender) args.arg4;
                     final int returnCode = args.argi1;
                     args.recycle();
 
@@ -459,7 +445,7 @@
      * Checks if the permissions still need to be confirmed.
      *
      * <p>This is dependant on the identity of the installer, hence this cannot be cached if the
-     * installer might still {@link #transfer(String, IntentSender) change}.
+     * installer might still {@link #transfer(String) change}.
      *
      * @return {@code true} iff we need to ask to confirm the permissions?
      */
@@ -1403,11 +1389,13 @@
         }
     }
 
-    private int assertCanBeTransferredAndReturnNewOwner(String packageName)
-            throws PackageManager.NameNotFoundException {
+    @Override
+    public void transfer(String packageName) {
+        Objects.requireNonNull(packageName);
+
         ApplicationInfo newOwnerAppInfo = mPm.getApplicationInfo(packageName, 0, userId);
         if (newOwnerAppInfo == null) {
-            throw new PackageManager.NameNotFoundException(packageName);
+            throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
         }
 
         if (PackageManager.PERMISSION_GRANTED != mPm.checkUidPermission(
@@ -1422,106 +1410,31 @@
             throw new SecurityException("Can only transfer sessions that use public options");
         }
 
-        return newOwnerAppInfo.uid;
-    }
-
-    @Override
-    public void transfer(String packageName, IntentSender statusReceiver) {
-        Objects.requireNonNull(statusReceiver);
-        Objects.requireNonNull(packageName);
-
-        try {
-            assertCanBeTransferredAndReturnNewOwner(packageName);
-        } catch (PackageManager.NameNotFoundException e) {
-            throw new ParcelableException(e);
-        }
+        List<PackageInstallerSession> childSessions = getChildSessions();
 
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotSealedLocked("transfer");
-        }
 
-        final SomeArgs args = SomeArgs.obtain();
-        args.arg1 = packageName;
-        args.arg2 = statusReceiver;
-
-        mHandler.obtainMessage(MSG_TRANSFER, args).sendToTarget();
-    }
-
-    private void handleTransfer(IntentSender statusReceiver, String packageName) {
-        List<PackageInstallerSession> childSessions = getChildSessions();
-
-        try {
-            final int uid = assertCanBeTransferredAndReturnNewOwner(packageName);
-
-            synchronized (mLock) {
-                assertPreparedAndNotSealedLocked("transfer");
-
-                try {
-                    sealAndValidateLocked(childSessions);
-                } catch (StreamingException e) {
-                    throw new IllegalArgumentException("Streaming failed", e);
-                } catch (PackageManagerException e) {
-                    throw new IllegalArgumentException("Package is not valid", e);
-                }
-
-                if (!mPackageName.equals(mInstallSource.installerPackageName)) {
-                    throw new SecurityException(
-                            "Can only transfer sessions that update the original installer");
-                }
-
-                mInstallerUid = uid;
-                mInstallSource = InstallSource.create(packageName, null, packageName);
+            try {
+                sealLocked(childSessions);
+            } catch (PackageManagerException e) {
+                throw new IllegalArgumentException("Package is not valid", e);
             }
-        } catch (PackageManager.NameNotFoundException e) {
-            onSessionTransferStatus(statusReceiver, packageName,
-                    PackageInstaller.STATUS_FAILURE_NAME_NOT_FOUND, e.getMessage());
-            return;
-        } catch (IllegalStateException e) {
-            onSessionTransferStatus(statusReceiver, packageName,
-                    PackageInstaller.STATUS_FAILURE_ILLEGAL_STATE, e.getMessage());
-            return;
-        } catch (SecurityException e) {
-            onSessionTransferStatus(statusReceiver, packageName,
-                    PackageInstaller.STATUS_FAILURE_SECURITY, e.getMessage());
-            return;
-        } catch (Throwable e) {
-            onSessionTransferStatus(statusReceiver, packageName, PackageInstaller.STATUS_FAILURE,
-                    e.getMessage());
-            return;
+
+            if (!mPackageName.equals(mInstallSource.installerPackageName)) {
+                throw new SecurityException("Can only transfer sessions that update the original "
+                        + "installer");
+            }
+
+            mInstallerUid = newOwnerAppInfo.uid;
+            mInstallSource = InstallSource.create(packageName, null, packageName);
         }
 
         // Persist the fact that we've sealed ourselves to prevent
         // mutations of any hard links we create. We do this without holding
         // the session lock, since otherwise it's a lock inversion.
         mCallback.onSessionSealedBlocking(this);
-
-        // Report success.
-        onSessionTransferStatus(statusReceiver, packageName, PackageInstaller.STATUS_SUCCESS, null);
-    }
-
-    private void onSessionTransferStatus(IntentSender statusReceiver, String otherPackageName,
-            int status, String statusMessage) {
-        final String packageName;
-        synchronized (mLock) {
-            packageName = mPackageName;
-        }
-
-        final Intent fillIn = new Intent();
-        fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName);
-        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-        fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, otherPackageName);
-
-        fillIn.putExtra(PackageInstaller.EXTRA_STATUS, status);
-        if (!TextUtils.isEmpty(statusMessage)) {
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, statusMessage);
-        }
-
-        try {
-            statusReceiver.sendIntent(mContext, 0, fillIn, null, null);
-        } catch (IntentSender.SendIntentException ignored) {
-        }
-
     }
 
     private void handleCommit() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d0f91c2..07aec4a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -124,6 +124,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
+import android.app.ApplicationPackageManager;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
 import android.app.IActivityManager;
@@ -2721,6 +2722,7 @@
         t.traceBegin("get system config");
         SystemConfig systemConfig = SystemConfig.getInstance();
         mAvailableFeatures = systemConfig.getAvailableFeatures();
+        ApplicationPackageManager.invalidateSysFeatureCache();
         t.traceEnd();
 
         mProtectedPackages = new ProtectedPackages(mContext);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 5adab37..ad4f6ff 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -81,6 +81,7 @@
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -132,6 +133,7 @@
 class PackageManagerShellCommand extends ShellCommand {
     /** Path for streaming APK content */
     private static final String STDIN_PATH = "-";
+    private static final byte[] STDIN_PATH_BYTES = "-".getBytes(StandardCharsets.UTF_8);
     /** Path where ART profiles snapshots are dumped for the shell user */
     private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
     private static final int DEFAULT_WAIT_MS = 60 * 1000;
@@ -472,6 +474,7 @@
                 }
             }
         }
+
         params.sessionParams.setSize(sessionSize);
     }
     /**
@@ -1170,57 +1173,52 @@
 
     private int doRunInstall(final InstallParams params) throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
-        final boolean streaming = params.sessionParams.dataLoaderParams != null;
 
-        ArrayList<String> inPaths = getRemainingArgs();
-        if (inPaths.isEmpty()) {
-            inPaths.add(STDIN_PATH);
-        }
-
-        final boolean hasSplits = inPaths.size() > 1;
-
-        if (STDIN_PATH.equals(inPaths.get(0))) {
-            if (hasSplits) {
-                pw.println("Error: can't specify SPLIT(s) along with STDIN");
-                return 1;
-            }
-            if (params.sessionParams.sizeBytes == -1) {
-                pw.println("Error: must either specify a package size or an APK file");
-                return 1;
-            }
-        }
-
+        final boolean isStreaming = params.sessionParams.dataLoaderParams != null;
         final boolean isApex =
                 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
+
+        ArrayList<String> args = getRemainingArgs();
+
+        final boolean fromStdIn = args.isEmpty() || STDIN_PATH.equals(args.get(0));
+        final boolean hasSplits = args.size() > 1;
+
+        if (fromStdIn && params.sessionParams.sizeBytes == -1) {
+            pw.println("Error: must either specify a package size or an APK file");
+            return 1;
+        }
+
         if (isApex && hasSplits) {
             pw.println("Error: can't specify SPLIT(s) for APEX");
             return 1;
         }
 
-        if (!streaming) {
-            setParamsSize(params, inPaths);
+        if (!isStreaming) {
+            if (fromStdIn && hasSplits) {
+                pw.println("Error: can't specify SPLIT(s) along with STDIN");
+                return 1;
+            }
+
+            if (args.isEmpty()) {
+                args.add(STDIN_PATH);
+            } else {
+                setParamsSize(params, args);
+            }
         }
 
         final int sessionId = doCreateSession(params.sessionParams,
                 params.installerPackageName, params.userId);
         boolean abandonSession = true;
         try {
-            for (String inPath : inPaths) {
-                if (streaming) {
-                    String name = new File(inPath).getName();
-                    byte[] metadata = inPath.getBytes(StandardCharsets.UTF_8);
-                    if (doAddFile(sessionId, name, params.sessionParams.sizeBytes, metadata,
-                            false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
-                        return 1;
-                    }
-                } else {
-                    String splitName = hasSplits ? new File(inPath).getName()
-                            : "base." + (isApex ? "apex" : "apk");
-
-                    if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
-                            false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
-                        return 1;
-                    }
+            if (isStreaming) {
+                if (doAddFiles(sessionId, args, params.sessionParams.sizeBytes, isApex)
+                        != PackageInstaller.STATUS_SUCCESS) {
+                    return 1;
+                }
+            } else {
+                if (doWriteSplits(sessionId, args, params.sessionParams.sizeBytes, isApex)
+                        != PackageInstaller.STATUS_SUCCESS) {
+                    return 1;
                 }
             }
             if (doCommitSession(sessionId, false /*logSuccess*/)
@@ -2519,7 +2517,7 @@
         }
 
         name = arg;
-        UserInfo info;
+        UserInfo info = null;
         IUserManager um = IUserManager.Stub.asInterface(
                 ServiceManager.getService(Context.USER_SERVICE));
         IAccountManager accm = IAccountManager.Stub.asInterface(
@@ -2527,17 +2525,22 @@
         if (userType == null) {
             userType = UserInfo.getDefaultUserType(flags);
         }
-        if (UserManager.isUserTypeRestricted(userType)) {
-            // In non-split user mode, userId can only be SYSTEM
-            int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
-            info = um.createRestrictedProfile(name, parentUserId);
-            accm.addSharedAccountsFromParentUser(parentUserId, userId,
-                    (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
-        } else if (userId < 0) {
-            info = preCreateOnly ?
-                    um.preCreateUser(userType) : um.createUser(name, userType, flags);
-        } else {
-            info = um.createProfileForUser(name, userType, flags, userId, null);
+        try {
+            if (UserManager.isUserTypeRestricted(userType)) {
+                // In non-split user mode, userId can only be SYSTEM
+                int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
+                info = um.createRestrictedProfileWithThrow(name, parentUserId);
+                accm.addSharedAccountsFromParentUser(parentUserId, userId,
+                        (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
+            } else if (userId < 0) {
+                info = preCreateOnly ?
+                        um.preCreateUserWithThrow(userType) :
+                        um.createUserWithThrow(name, userType, flags);
+            } else {
+                info = um.createProfileForUserWithThrow(name, userType, flags, userId, null);
+            }
+        } catch (ServiceSpecificException e) {
+            getErrPrintWriter().println("Error: " + e);
         }
 
         if (info != null) {
@@ -2956,23 +2959,71 @@
         return sessionId;
     }
 
-    private int doAddFile(int sessionId, String name, long sizeBytes, byte[] metadata,
-            boolean logSuccess) throws RemoteException {
+    private int doAddFiles(int sessionId, ArrayList<String> args, long sessionSizeBytes,
+            boolean isApex) throws RemoteException {
         PackageInstaller.Session session = new PackageInstaller.Session(
                 mInterface.getPackageInstaller().openSession(sessionId));
         try {
-            session.addFile(name, sizeBytes, metadata);
-
-            if (logSuccess) {
-                getOutPrintWriter().println("Success");
+            // 1. Single file from stdin.
+            if (args.isEmpty() || STDIN_PATH.equals(args.get(0))) {
+                String name = "base." + (isApex ? "apex" : "apk");
+                session.addFile(name, sessionSizeBytes, STDIN_PATH_BYTES);
+                return 0;
             }
 
+            for (String arg : args) {
+                final int delimLocation = arg.indexOf(':');
+
+                // 2. File with specified size read from stdin.
+                if (delimLocation != -1) {
+                    String name = arg.substring(0, delimLocation);
+                    String sizeStr = arg.substring(delimLocation + 1);
+                    long sizeBytes;
+
+                    if (TextUtils.isEmpty(name)) {
+                        getErrPrintWriter().println("Empty file name in: " + arg);
+                        return 1;
+                    }
+                    try {
+                        sizeBytes = Long.parseUnsignedLong(sizeStr);
+                    } catch (NumberFormatException e) {
+                        getErrPrintWriter().println("Unable to parse size from: " + arg);
+                        return 1;
+                    }
+
+                    session.addFile(name, sizeBytes, STDIN_PATH_BYTES);
+                    continue;
+                }
+
+                // 3. Local file.
+                final String inPath = arg;
+
+                String name = new File(inPath).getName();
+                byte[] metadata = inPath.getBytes(StandardCharsets.UTF_8);
+
+                session.addFile(name, -1, metadata);
+            }
             return 0;
         } finally {
             IoUtils.closeQuietly(session);
         }
     }
 
+    private int doWriteSplits(int sessionId, ArrayList<String> splitPaths, long sessionSizeBytes,
+            boolean isApex) throws RemoteException {
+        final boolean multipleSplits = splitPaths.size() > 1;
+        for (String splitPath : splitPaths) {
+            String splitName = multipleSplits ? new File(splitPath).getName()
+                    : "base." + (isApex ? "apex" : "apk");
+
+            if (doWriteSplit(sessionId, splitPath, sessionSizeBytes, splitName,
+                    false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
+                return 1;
+            }
+        }
+        return 0;
+    }
+
     private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
             boolean logSuccess) throws RemoteException {
         PackageInstaller.Session session = null;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 4f18cb4..5d948b2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -92,6 +92,8 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.XmlUtils;
+import com.android.permission.persistence.RuntimePermissionsPersistence;
+import com.android.permission.persistence.RuntimePermissionsState;
 import com.android.server.LocalServices;
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.permission.BasePermission;
@@ -5096,6 +5098,9 @@
         private static final int UPGRADE_VERSION = -1;
         private static final int INITIAL_VERSION = 0;
 
+        private final RuntimePermissionsPersistence mPersistence =
+                RuntimePermissionsPersistence.createInstance();
+
         private final Handler mHandler = new MyHandler();
 
         private final Object mPersistenceLock;
@@ -5185,98 +5190,72 @@
         }
 
         private void writePermissionsSync(int userId) {
-            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId),
-                    "package-perms-" + userId);
-
-            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
-            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
-
+            RuntimePermissionsState runtimePermissions;
             synchronized (mPersistenceLock) {
                 mWriteScheduled.delete(userId);
 
-                final int packageCount = mPackages.size();
-                for (int i = 0; i < packageCount; i++) {
+                int version = mVersions.get(userId, INITIAL_VERSION);
+
+                String fingerprint = mFingerprints.get(userId);
+
+                Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
+                        new ArrayMap<>();
+                int packagesSize = mPackages.size();
+                for (int i = 0; i < packagesSize; i++) {
                     String packageName = mPackages.keyAt(i);
                     PackageSetting packageSetting = mPackages.valueAt(i);
                     if (packageSetting.sharedUser == null) {
-                        PermissionsState permissionsState = packageSetting.getPermissionsState();
-                        List<PermissionState> permissionsStates = permissionsState
-                                .getRuntimePermissionStates(userId);
-                        if (!permissionsStates.isEmpty()) {
-                            permissionsForPackage.put(packageName, permissionsStates);
+                        List<RuntimePermissionsState.PermissionState> permissions =
+                                getPermissionsFromPermissionsState(
+                                        packageSetting.getPermissionsState(), userId);
+                        if (permissions != null) {
+                            packagePermissions.put(packageName, permissions);
                         }
                     }
                 }
 
-                final int sharedUserCount = mSharedUsers.size();
-                for (int i = 0; i < sharedUserCount; i++) {
+                Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
+                        new ArrayMap<>();
+                final int sharedUsersSize = mSharedUsers.size();
+                for (int i = 0; i < sharedUsersSize; i++) {
                     String sharedUserName = mSharedUsers.keyAt(i);
-                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
-                    PermissionsState permissionsState = sharedUser.getPermissionsState();
-                    List<PermissionState> permissionsStates = permissionsState
-                            .getRuntimePermissionStates(userId);
-                    if (!permissionsStates.isEmpty()) {
-                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
+                    SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i);
+                    List<RuntimePermissionsState.PermissionState> permissions =
+                            getPermissionsFromPermissionsState(
+                                    sharedUserSetting.getPermissionsState(), userId);
+                    if (permissions != null) {
+                        sharedUserPermissions.put(sharedUserName, permissions);
                     }
                 }
+
+                runtimePermissions = new RuntimePermissionsState(version, fingerprint,
+                        packagePermissions, sharedUserPermissions);
             }
 
-            FileOutputStream out = null;
-            try {
-                out = destination.startWrite();
+            mPersistence.write(runtimePermissions, UserHandle.of(userId));
+        }
 
-                XmlSerializer serializer = Xml.newSerializer();
-                serializer.setOutput(out, StandardCharsets.UTF_8.name());
-                serializer.setFeature(
-                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
-                serializer.startDocument(null, true);
-
-                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
-
-                final int version = mVersions.get(userId, INITIAL_VERSION);
-                serializer.attribute(null, ATTR_VERSION, Integer.toString(version));
-
-                String fingerprint = mFingerprints.get(userId);
-                if (fingerprint != null) {
-                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
-                }
-
-                final int packageCount = permissionsForPackage.size();
-                for (int i = 0; i < packageCount; i++) {
-                    String packageName = permissionsForPackage.keyAt(i);
-                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
-                    serializer.startTag(null, TAG_PACKAGE);
-                    serializer.attribute(null, ATTR_NAME, packageName);
-                    writePermissions(serializer, permissionStates);
-                    serializer.endTag(null, TAG_PACKAGE);
-                }
-
-                final int sharedUserCount = permissionsForSharedUser.size();
-                for (int i = 0; i < sharedUserCount; i++) {
-                    String packageName = permissionsForSharedUser.keyAt(i);
-                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
-                    serializer.startTag(null, TAG_SHARED_USER);
-                    serializer.attribute(null, ATTR_NAME, packageName);
-                    writePermissions(serializer, permissionStates);
-                    serializer.endTag(null, TAG_SHARED_USER);
-                }
-
-                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
-
-                serializer.endDocument();
-                destination.finishWrite(out);
-
-                if (Build.FINGERPRINT.equals(fingerprint)) {
-                    mDefaultPermissionsGranted.put(userId, true);
-                }
-            // Any error while writing is fatal.
-            } catch (Throwable t) {
-                Slog.wtf(PackageManagerService.TAG,
-                        "Failed to write settings, restoring backup", t);
-                destination.failWrite(out);
-            } finally {
-                IoUtils.closeQuietly(out);
+        @Nullable
+        private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState(
+                @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
+            List<PermissionState> permissionStates = permissionsState.getRuntimePermissionStates(
+                    userId);
+            if (permissionStates.isEmpty()) {
+                return null;
             }
+
+            List<RuntimePermissionsState.PermissionState> permissions =
+                    new ArrayList<>();
+            int permissionStatesSize = permissionStates.size();
+            for (int i = 0; i < permissionStatesSize; i++) {
+                PermissionState permissionState = permissionStates.get(i);
+
+                RuntimePermissionsState.PermissionState permission =
+                        new RuntimePermissionsState.PermissionState(permissionState.getName(),
+                                permissionState.isGranted(), permissionState.getFlags());
+                permissions.add(permission);
+            }
+            return permissions;
         }
 
         @GuardedBy("Settings.this.mLock")
@@ -5311,11 +5290,88 @@
         }
 
         public void deleteUserRuntimePermissionsFile(int userId) {
-            getUserRuntimePermissionsFile(userId).delete();
+            mPersistence.delete(UserHandle.of(userId));
         }
 
         @GuardedBy("Settings.this.mLock")
         public void readStateForUserSyncLPr(int userId) {
+            RuntimePermissionsState runtimePermissions = mPersistence.read(UserHandle.of(userId));
+            if (runtimePermissions == null) {
+                readLegacyStateForUserSyncLPr(userId);
+                writePermissionsForUserAsyncLPr(userId);
+                return;
+            }
+
+            // If the runtime permissions file exists but the version is not set this is
+            // an upgrade from P->Q. Hence mark it with the special UPGRADE_VERSION.
+            int version = runtimePermissions.getVersion();
+            if (version == RuntimePermissionsState.NO_VERSION) {
+                version = UPGRADE_VERSION;
+            }
+            mVersions.put(userId, version);
+
+            String fingerprint = runtimePermissions.getFingerprint();
+            mFingerprints.put(userId, fingerprint);
+            boolean defaultPermissionsGranted = Build.FINGERPRINT.equals(fingerprint);
+            mDefaultPermissionsGranted.put(userId, defaultPermissionsGranted);
+
+            for (Map.Entry<String, List<RuntimePermissionsState.PermissionState>> entry
+                    : runtimePermissions.getPackagePermissions().entrySet()) {
+                String packageName = entry.getKey();
+                List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
+
+                PackageSetting packageSetting = mPackages.get(packageName);
+                if (packageSetting == null) {
+                    Slog.w(PackageManagerService.TAG, "Unknown package:" + packageName);
+                    continue;
+                }
+                readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(), userId);
+            }
+
+            for (Map.Entry<String, List<RuntimePermissionsState.PermissionState>> entry
+                    : runtimePermissions.getSharedUserPermissions().entrySet()) {
+                String sharedUserName = entry.getKey();
+                List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
+
+                SharedUserSetting sharedUserSetting = mSharedUsers.get(sharedUserName);
+                if (sharedUserSetting == null) {
+                    Slog.w(PackageManagerService.TAG, "Unknown shared user:" + sharedUserName);
+                    continue;
+                }
+                readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(),
+                        userId);
+            }
+        }
+
+        private void readPermissionsStateLpr(
+                @NonNull List<RuntimePermissionsState.PermissionState> permissions,
+                @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
+            int permissionsSize = permissions.size();
+            for (int i = 0; i < permissionsSize; i++) {
+                RuntimePermissionsState.PermissionState permission = permissions.get(i);
+
+                String name = permission.getName();
+                BasePermission basePermission = mPermissions.getPermission(name);
+                if (basePermission == null) {
+                    Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
+                    continue;
+                }
+                boolean granted = permission.isGranted();
+                int flags = permission.getFlags();
+
+                if (granted) {
+                    permissionsState.grantRuntimePermission(basePermission, userId);
+                    permissionsState.updatePermissionFlags(basePermission, userId,
+                            PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
+                } else {
+                    permissionsState.updatePermissionFlags(basePermission, userId,
+                            PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
+                }
+            }
+        }
+
+        @GuardedBy("Settings.this.mLock")
+        private void readLegacyStateForUserSyncLPr(int userId) {
             File permissionsFile = getUserRuntimePermissionsFile(userId);
             if (!permissionsFile.exists()) {
                 return;
@@ -5435,19 +5491,6 @@
             }
         }
 
-        private void writePermissions(XmlSerializer serializer,
-                List<PermissionState> permissionStates) throws IOException {
-            for (PermissionState permissionState : permissionStates) {
-                serializer.startTag(null, TAG_ITEM);
-                serializer.attribute(null, ATTR_NAME,permissionState.getName());
-                serializer.attribute(null, ATTR_GRANTED,
-                        String.valueOf(permissionState.isGranted()));
-                serializer.attribute(null, ATTR_FLAGS,
-                        Integer.toHexString(permissionState.getFlags()));
-                serializer.endTag(null, TAG_ITEM);
-            }
-        }
-
         private final class MyHandler extends Handler {
             public MyHandler() {
                 super(BackgroundThread.getHandler().getLooper());
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 66a2b01..5511a54 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -67,6 +67,7 @@
 import android.os.ResultReceiver;
 import android.os.SELinux;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
 import android.os.SystemClock;
@@ -74,6 +75,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManager.EnforcingUser;
+import android.os.UserManager.QuietModeFlag;
 import android.os.UserManagerInternal;
 import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.os.storage.StorageManager;
@@ -914,7 +916,7 @@
 
     @Override
     public boolean requestQuietModeEnabled(@NonNull String callingPackage, boolean enableQuietMode,
-            @UserIdInt int userId, @Nullable IntentSender target) {
+            @UserIdInt int userId, @Nullable IntentSender target, @QuietModeFlag int flags) {
         Objects.requireNonNull(callingPackage);
 
         if (enableQuietMode && target != null) {
@@ -925,24 +927,24 @@
         ensureCanModifyQuietMode(callingPackage, Binder.getCallingUid(), userId, target != null);
         final long identity = Binder.clearCallingIdentity();
         try {
-            boolean result = false;
             if (enableQuietMode) {
                 setQuietModeEnabled(
                         userId, true /* enableQuietMode */, target, callingPackage);
-                result = true;
-            } else {
-                boolean needToShowConfirmCredential =
-                        mLockPatternUtils.isSecure(userId)
-                                && !StorageManager.isUserKeyUnlocked(userId);
-                if (needToShowConfirmCredential) {
-                    showConfirmCredentialToDisableQuietMode(userId, target);
-                } else {
-                    setQuietModeEnabled(
-                            userId, false /* enableQuietMode */, target, callingPackage);
-                    result = true;
-                }
+                return true;
             }
-            return result;
+            boolean needToShowConfirmCredential =
+                    mLockPatternUtils.isSecure(userId)
+                            && !StorageManager.isUserKeyUnlocked(userId);
+            if (needToShowConfirmCredential) {
+                if ((flags & UserManager.QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED) != 0) {
+                    return false;
+                }
+                showConfirmCredentialToDisableQuietMode(userId, target);
+                return false;
+            }
+            setQuietModeEnabled(
+                    userId, false /* enableQuietMode */, target, callingPackage);
+            return true;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -1537,12 +1539,14 @@
 
     @Override
     public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
-        checkManageUsersPermission("update users");
-        if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) {
-            Slog.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled.");
-            return;
+        try {
+            checkManageUsersPermission("update users");
+            enforceUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId,
+                    "Cannot set user icon");
+            mLocalService.setUserIcon(userId, bitmap);
+        } catch (UserManager.CheckedUserOperationException e) {
+            throw e.toServiceSpecificException();
         }
-        mLocalService.setUserIcon(userId, bitmap);
     }
 
 
@@ -3036,34 +3040,53 @@
 
     /**
      * Creates a profile user. Used for actual profiles, like
-     * {@link UserManager#USER_TYPE_PROFILE_MANAGED}, as well as for
-     * {@link UserManager#USER_TYPE_FULL_RESTRICTED}.
+     * {@link UserManager#USER_TYPE_PROFILE_MANAGED},
+     * as well as for {@link UserManager#USER_TYPE_FULL_RESTRICTED}.
      */
     @Override
-    public UserInfo createProfileForUser(String name, @NonNull String userType,
-            @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) {
+    public UserInfo createProfileForUserWithThrow(String name, @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)
+            throws ServiceSpecificException {
         checkManageOrCreateUsersPermission(flags);
-        return createUserInternal(name, userType, flags, userId, disallowedPackages);
+        try {
+            return createUserInternal(name, userType, flags, userId, disallowedPackages);
+        } catch (UserManager.CheckedUserOperationException e) {
+            throw e.toServiceSpecificException();
+        }
     }
 
-    /** @see #createProfileForUser */
+    /**
+     * @see #createProfileForUser
+     */
     @Override
-    public UserInfo createProfileForUserEvenWhenDisallowed(String name, @NonNull String userType,
-            @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages) {
+    public UserInfo createProfileForUserEvenWhenDisallowedWithThrow(String name,
+            @NonNull String userType,
+            @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)
+            throws ServiceSpecificException {
         checkManageOrCreateUsersPermission(flags);
-        return createUserInternalUnchecked(name, userType, flags, userId,
-                /* preCreate= */ false, disallowedPackages);
+        try {
+            return createUserInternalUnchecked(name, userType, flags, userId,
+                    /* preCreate= */ false, disallowedPackages);
+        } catch (UserManager.CheckedUserOperationException e) {
+            throw e.toServiceSpecificException();
+        }
     }
 
     @Override
-    public UserInfo createUser(String name, @NonNull String userType, @UserInfoFlag int flags) {
+    public UserInfo createUserWithThrow(String name, @NonNull String userType,
+            @UserInfoFlag int flags)
+            throws ServiceSpecificException {
         checkManageOrCreateUsersPermission(flags);
-        return createUserInternal(name, userType, flags, UserHandle.USER_NULL,
-                /* disallowedPackages= */ null);
+        try {
+            return createUserInternal(name, userType, flags, UserHandle.USER_NULL,
+                    /* disallowedPackages= */ null);
+        } catch (UserManager.CheckedUserOperationException e) {
+            throw e.toServiceSpecificException();
+        }
     }
 
     @Override
-    public UserInfo preCreateUser(String userType) {
+    public UserInfo preCreateUserWithThrow(String userType) throws ServiceSpecificException {
         final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
         final int flags = userTypeDetails != null ? userTypeDetails.getDefaultUserInfoFlags() : 0;
 
@@ -3073,28 +3096,32 @@
                 "cannot pre-create user of type " + userType);
         Slog.i(LOG_TAG, "Pre-creating user of type " + userType);
 
-        return createUserInternalUnchecked(/* name= */ null, userType, flags,
-                /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true,
-                /* disallowedPackages= */ null);
+        try {
+            return createUserInternalUnchecked(/* name= */ null, userType, flags,
+                    /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true,
+                    /* disallowedPackages= */ null);
+        } catch (UserManager.CheckedUserOperationException e) {
+            throw e.toServiceSpecificException();
+        }
     }
 
     private UserInfo createUserInternal(@Nullable String name, @NonNull String userType,
             @UserInfoFlag int flags, @UserIdInt int parentId,
-            @Nullable String[] disallowedPackages) {
+            @Nullable String[] disallowedPackages)
+            throws UserManager.CheckedUserOperationException {
         String restriction = (UserManager.isUserTypeManagedProfile(userType))
                 ? UserManager.DISALLOW_ADD_MANAGED_PROFILE
                 : UserManager.DISALLOW_ADD_USER;
-        if (hasUserRestriction(restriction, UserHandle.getCallingUserId())) {
-            Slog.w(LOG_TAG, "Cannot add user. " + restriction + " is enabled.");
-            return null;
-        }
+        enforceUserRestriction(restriction, UserHandle.getCallingUserId(),
+                "Cannot add user");
         return createUserInternalUnchecked(name, userType, flags, parentId,
                 /* preCreate= */ false, disallowedPackages);
     }
 
     private UserInfo createUserInternalUnchecked(@Nullable String name,
             @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
-            boolean preCreate, @Nullable String[] disallowedPackages) {
+            boolean preCreate, @Nullable String[] disallowedPackages)
+            throws UserManager.CheckedUserOperationException {
         final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
         t.traceBegin("createUser-" + flags);
         try {
@@ -3108,7 +3135,7 @@
     private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
             @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
             boolean preCreate, @Nullable String[] disallowedPackages,
-            @NonNull TimingsTraceAndSlog t) {
+            @NonNull TimingsTraceAndSlog t) throws UserManager.CheckedUserOperationException {
         final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
         if (userTypeDetails == null) {
             Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType);
@@ -3143,8 +3170,8 @@
         DeviceStorageMonitorInternal dsm = LocalServices
                 .getService(DeviceStorageMonitorInternal.class);
         if (dsm.isMemoryLow()) {
-            Slog.w(LOG_TAG, "Cannot add user. Not enough space on disk.");
-            return null;
+            throwCheckedUserOperationException("Cannot add user. Not enough space on disk.",
+                    UserManager.USER_OPERATION_ERROR_LOW_STORAGE);
         }
 
         final boolean isProfile = userTypeDetails.isProfile();
@@ -3163,41 +3190,50 @@
                     synchronized (mUsersLock) {
                         parent = getUserDataLU(parentId);
                     }
-                    if (parent == null) return null;
+                    if (parent == null) {
+                        throwCheckedUserOperationException(
+                                "Cannot find user data for parent user " + parentId,
+                                UserManager.USER_OPERATION_ERROR_UNKNOWN);
+                    }
                 }
                 if (!preCreate && !canAddMoreUsersOfType(userTypeDetails)) {
-                    Slog.e(LOG_TAG, "Cannot add more users of type " + userType
-                            + ". Maximum number of that type already exists.");
-                    return null;
+                    throwCheckedUserOperationException("Cannot add more users of type " + userType
+                                    + ". Maximum number of that type already exists.",
+                            UserManager.USER_OPERATION_ERROR_MAX_USERS);
                 }
                 // TODO(b/142482943): Perhaps let the following code apply to restricted users too.
                 if (isProfile && !canAddMoreProfilesToUser(userType, parentId, false)) {
-                    Slog.e(LOG_TAG, "Cannot add more profiles of type " + userType
-                            + " for user " + parentId);
-                    return null;
+                    throwCheckedUserOperationException(
+                            "Cannot add more profiles of type " + userType
+                                    + " for user " + parentId,
+                            UserManager.USER_OPERATION_ERROR_MAX_USERS);
                 }
                 if (!isGuest && !isProfile && !isDemo && isUserLimitReached()) {
                     // If we're not adding a guest/demo user or a profile and the 'user limit' has
                     // been reached, cannot add a user.
-                    Slog.e(LOG_TAG, "Cannot add user. Maximum user limit is reached.");
-                    return null;
+                    throwCheckedUserOperationException(
+                            "Cannot add user. Maximum user limit is reached.",
+                            UserManager.USER_OPERATION_ERROR_MAX_USERS);
                 }
                 // In legacy mode, restricted profile's parent can only be the owner user
                 if (isRestricted && !UserManager.isSplitSystemUser()
                         && (parentId != UserHandle.USER_SYSTEM)) {
-                    Slog.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
-                    return null;
+                    throwCheckedUserOperationException(
+                            "Cannot add restricted profile - parent user must be owner",
+                            UserManager.USER_OPERATION_ERROR_UNKNOWN);
                 }
                 if (isRestricted && UserManager.isSplitSystemUser()) {
                     if (parent == null) {
-                        Slog.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
-                                + "specified");
-                        return null;
+                        throwCheckedUserOperationException(
+                                "Cannot add restricted profile - parent user must be specified",
+                                UserManager.USER_OPERATION_ERROR_UNKNOWN);
                     }
                     if (!parent.info.canHaveProfile()) {
-                        Slog.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
-                                + "created for the specified parent user id " + parentId);
-                        return null;
+                        throwCheckedUserOperationException(
+                                "Cannot add restricted profile - profiles cannot be created for "
+                                        + "the specified parent user id "
+                                        + parentId,
+                                UserManager.USER_OPERATION_ERROR_UNKNOWN);
                     }
                 }
 
@@ -3463,9 +3499,9 @@
      * @hide
      */
     @Override
-    public UserInfo createRestrictedProfile(String name, int parentUserId) {
+    public UserInfo createRestrictedProfileWithThrow(String name, int parentUserId) {
         checkManageOrCreateUsersPermission("setupRestrictedProfile");
-        final UserInfo user = createProfileForUser(
+        final UserInfo user = createProfileForUserWithThrow(
                 name, UserManager.USER_TYPE_FULL_RESTRICTED, 0, parentUserId, null);
         if (user == null) {
             return null;
@@ -4714,7 +4750,8 @@
 
         @Override
         public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType,
-                @UserInfoFlag int flags, String[] disallowedPackages) {
+                @UserInfoFlag int flags, String[] disallowedPackages)
+                throws UserManager.CheckedUserOperationException {
             return createUserInternalUnchecked(name, userType, flags,
                     UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages);
         }
@@ -4874,6 +4911,38 @@
         }
     }
 
+    /**
+     * Check if user has restrictions
+     * @param restriction restrictions to check
+     * @param userId id of the user
+     *
+     * @throws {@link android.os.UserManager.CheckedUserOperationException} if user has any of the
+     *      specified restrictions
+     */
+    private void enforceUserRestriction(String restriction, @UserIdInt int userId, String message)
+            throws UserManager.CheckedUserOperationException {
+        if (hasUserRestriction(restriction, userId)) {
+            String errorMessage = (message != null ? (message + ": ") : "")
+                    + restriction + " is enabled.";
+            Slog.w(LOG_TAG, errorMessage);
+            throw new UserManager.CheckedUserOperationException(errorMessage,
+                    UserManager.USER_OPERATION_ERROR_UNKNOWN);
+        }
+    }
+
+    /**
+     * Throws CheckedUserOperationException and shows error log
+     * @param message message for exception and logging
+     * @param userOperationResult result/error code
+     * @throws UserManager.CheckedUserOperationException
+     */
+    private void throwCheckedUserOperationException(@NonNull String message,
+            @UserManager.UserOperationResult int userOperationResult)
+            throws UserManager.CheckedUserOperationException {
+        Slog.e(LOG_TAG, message);
+        throw new UserManager.CheckedUserOperationException(message, userOperationResult);
+    }
+
     /* Remove all the users except of the system one. */
     private void removeNonSystemUsers() {
         ArrayList<UserInfo> usersToRemove = new ArrayList<>();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ea83adb..ec9049e 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -46,7 +46,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -55,6 +54,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
@@ -1632,7 +1632,8 @@
                 // If a system window has focus, then it doesn't make sense
                 // right now to interact with applications.
                 if (info.layoutParamsType == TYPE_KEYGUARD_DIALOG
-                        || (info.layoutParamsPrivateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+                        || (info.layoutParamsType == TYPE_NOTIFICATION_SHADE
+                        && isKeyguardShowing())) {
                     // the "app" is keyguard, so give it the key
                     return 0;
                 }
@@ -2205,12 +2206,12 @@
 
     @Override
     public int getMaxWallpaperLayer() {
-        return getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
+        return getWindowLayerFromTypeLw(TYPE_NOTIFICATION_SHADE);
     }
 
     @Override
     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
-        return attrs.type == TYPE_STATUS_BAR;
+        return attrs.type == TYPE_NOTIFICATION_SHADE;
     }
 
     @Override
@@ -2221,6 +2222,7 @@
             return false;
         }
         switch (win.getAttrs().type) {
+            case TYPE_NOTIFICATION_SHADE:
             case TYPE_STATUS_BAR:
             case TYPE_NAVIGATION_BAR:
             case TYPE_WALLPAPER:
@@ -2228,7 +2230,7 @@
                 return false;
             default:
                 // Hide only windows below the keyguard host window.
-                return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
+                return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_NOTIFICATION_SHADE);
         }
     }
 
@@ -3445,7 +3447,6 @@
             mKeyguardOccluded = false;
             mKeyguardDelegate.setOccluded(false, true /* animate */);
             if (mKeyguardCandidate != null) {
-                mKeyguardCandidate.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD;
                 if (!mKeyguardDelegate.hasLockscreenWallpaper()) {
                     mKeyguardCandidate.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
                 }
@@ -3455,7 +3456,6 @@
             mKeyguardOccluded = true;
             mKeyguardDelegate.setOccluded(true, false /* animate */);
             if (mKeyguardCandidate != null) {
-                mKeyguardCandidate.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD;
                 mKeyguardCandidate.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
             }
             return true;
@@ -4658,6 +4658,12 @@
     }
 
     @Override
+    public boolean isKeyguardShowing() {
+        if (mKeyguardDelegate == null) return false;
+        return mKeyguardDelegate.isShowing();
+    }
+
+    @Override
     public boolean isKeyguardShowingAndNotOccluded() {
         if (mKeyguardDelegate == null) return false;
         return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index b014372..c39da5f 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -39,6 +39,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
 import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
@@ -812,55 +813,57 @@
                 return  16;
             case TYPE_STATUS_BAR:
                 return  17;
-            case TYPE_STATUS_BAR_PANEL:
+            case TYPE_NOTIFICATION_SHADE:
                 return  18;
-            case TYPE_STATUS_BAR_SUB_PANEL:
+            case TYPE_STATUS_BAR_PANEL:
                 return  19;
-            case TYPE_KEYGUARD_DIALOG:
+            case TYPE_STATUS_BAR_SUB_PANEL:
                 return  20;
+            case TYPE_KEYGUARD_DIALOG:
+                return  21;
             case TYPE_VOLUME_OVERLAY:
                 // the on-screen volume indicator and controller shown when the user
                 // changes the device volume
-                return  21;
+                return  22;
             case TYPE_SYSTEM_OVERLAY:
                 // the on-screen volume indicator and controller shown when the user
                 // changes the device volume
-                return  canAddInternalSystemWindow ? 22 : 11;
+                return  canAddInternalSystemWindow ? 23 : 11;
             case TYPE_NAVIGATION_BAR:
                 // the navigation bar, if available, shows atop most things
-                return  23;
+                return  24;
             case TYPE_NAVIGATION_BAR_PANEL:
                 // some panels (e.g. search) need to show on top of the navigation bar
-                return  24;
+                return  25;
             case TYPE_SCREENSHOT:
                 // screenshot selection layer shouldn't go above system error, but it should cover
                 // navigation bars at the very least.
-                return  25;
+                return  26;
             case TYPE_SYSTEM_ERROR:
                 // system-level error dialogs
-                return  canAddInternalSystemWindow ? 26 : 10;
+                return  canAddInternalSystemWindow ? 27 : 10;
             case TYPE_MAGNIFICATION_OVERLAY:
                 // used to highlight the magnified portion of a display
-                return  27;
+                return  28;
             case TYPE_DISPLAY_OVERLAY:
                 // used to simulate secondary display devices
-                return  28;
+                return  29;
             case TYPE_DRAG:
                 // the drag layer: input for drag-and-drop is associated with this window,
                 // which sits above all other focusable windows
-                return  29;
+                return  30;
             case TYPE_ACCESSIBILITY_OVERLAY:
                 // overlay put by accessibility services to intercept user interaction
-                return  30;
+                return  31;
             case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
-                return 31;
+                return 32;
             case TYPE_SECURE_SYSTEM_OVERLAY:
-                return  32;
-            case TYPE_BOOT_PROGRESS:
                 return  33;
+            case TYPE_BOOT_PROGRESS:
+                return  34;
             case TYPE_POINTER:
                 // the (mouse) pointer layer
-                return  34;
+                return  35;
             default:
                 Slog.e("WindowManager", "Unknown window type: " + type);
                 return APPLICATION_LAYER;
@@ -1195,6 +1198,11 @@
     public boolean isKeyguardOccluded();
 
     /**
+     * @return true if in keyguard is on.
+     */
+    boolean isKeyguardShowing();
+
+    /**
      * @return true if in keyguard is on and not occluded.
      */
     public boolean isKeyguardShowingAndNotOccluded();
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index d33c10c..9f4ca3c 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -23,6 +23,7 @@
 import android.annotation.WorkerThread;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -34,22 +35,21 @@
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.dump.DualDumpOutputStream;
 import com.android.internal.util.function.pooled.PooledLambda;
-
-import libcore.io.IoUtils;
+import com.android.role.persistence.RolesPersistence;
+import com.android.role.persistence.RolesState;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Stores the state of roles for a user.
@@ -71,6 +71,8 @@
     private static final String ATTRIBUTE_NAME = "name";
     private static final String ATTRIBUTE_PACKAGES_HASH = "packagesHash";
 
+    private final RolesPersistence mPersistence = RolesPersistence.createInstance();
+
     @UserIdInt
     private final int mUserId;
 
@@ -350,9 +352,7 @@
 
     @WorkerThread
     private void writeFile() {
-        int version;
-        String packagesHash;
-        ArrayMap<String, ArraySet<String>> roles;
+        RolesState roles;
         synchronized (mLock) {
             if (mDestroyed) {
                 return;
@@ -360,90 +360,45 @@
 
             mWriteScheduled = false;
 
-            version = mVersion;
-            packagesHash = mPackagesHash;
-            roles = snapshotRolesLocked();
+            roles = new RolesState(mVersion, mPackagesHash,
+                    (Map<String, Set<String>>) (Map<String, ?>) snapshotRolesLocked());
         }
 
-        AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
-        FileOutputStream out = null;
-        try {
-            out = atomicFile.startWrite();
-
-            XmlSerializer serializer = Xml.newSerializer();
-            serializer.setOutput(out, StandardCharsets.UTF_8.name());
-            serializer.setFeature(
-                    "http://xmlpull.org/v1/doc/features.html#indent-output", true);
-            serializer.startDocument(null, true);
-
-            serializeRoles(serializer, version, packagesHash, roles);
-
-            serializer.endDocument();
-            atomicFile.finishWrite(out);
-            Slog.i(LOG_TAG, "Wrote roles.xml successfully");
-        } catch (IllegalArgumentException | IllegalStateException | IOException e) {
-            Slog.wtf(LOG_TAG, "Failed to write roles.xml, restoring backup", e);
-            if (out != null) {
-                atomicFile.failWrite(out);
-            }
-        } finally {
-            IoUtils.closeQuietly(out);
-        }
+        mPersistence.write(roles, UserHandle.of(mUserId));
     }
 
-    @WorkerThread
-    private void serializeRoles(@NonNull XmlSerializer serializer, int version,
-            @Nullable String packagesHash, @NonNull ArrayMap<String, ArraySet<String>> roles)
-            throws IOException {
-        serializer.startTag(null, TAG_ROLES);
-
-        serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
-
-        if (packagesHash != null) {
-            serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
-        }
-
-        for (int i = 0, size = roles.size(); i < size; ++i) {
-            String roleName = roles.keyAt(i);
-            ArraySet<String> roleHolders = roles.valueAt(i);
-
-            serializer.startTag(null, TAG_ROLE);
-            serializer.attribute(null, ATTRIBUTE_NAME, roleName);
-            serializeRoleHolders(serializer, roleHolders);
-            serializer.endTag(null, TAG_ROLE);
-        }
-
-        serializer.endTag(null, TAG_ROLES);
-    }
-
-    @WorkerThread
-    private void serializeRoleHolders(@NonNull XmlSerializer serializer,
-            @NonNull ArraySet<String> roleHolders) throws IOException {
-        for (int i = 0, size = roleHolders.size(); i < size; ++i) {
-            String roleHolder = roleHolders.valueAt(i);
-
-            serializer.startTag(null, TAG_HOLDER);
-            serializer.attribute(null, ATTRIBUTE_NAME, roleHolder);
-            serializer.endTag(null, TAG_HOLDER);
-        }
-    }
-
-    /**
-     * Read the state from file.
-     */
     private void readFile() {
         synchronized (mLock) {
-            File file = getFile(mUserId);
-            try (FileInputStream in = new AtomicFile(file).openRead()) {
-                XmlPullParser parser = Xml.newPullParser();
-                parser.setInput(in, null);
-                parseXmlLocked(parser);
-                Slog.i(LOG_TAG, "Read roles.xml successfully");
-            } catch (FileNotFoundException e) {
-                Slog.i(LOG_TAG, "roles.xml not found");
-            } catch (XmlPullParserException | IOException e) {
-                throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
+            RolesState roles = mPersistence.read(UserHandle.of(mUserId));
+            if (roles == null) {
+                readLegacyFileLocked();
+                scheduleWriteFileLocked();
+                return;
             }
+
+            mVersion = roles.getVersion();
+            mPackagesHash = roles.getPackagesHash();
+
+            mRoles.clear();
+            for (Map.Entry<String, Set<String>> entry : roles.getRoles().entrySet()) {
+                String roleName = entry.getKey();
+                ArraySet<String> roleHolders = new ArraySet<>(entry.getValue());
+                mRoles.put(roleName, roleHolders);
+            }
+        }
+    }
+
+    private void readLegacyFileLocked() {
+        File file = getFile(mUserId);
+        try (FileInputStream in = new AtomicFile(file).openRead()) {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(in, null);
+            parseXmlLocked(parser);
+            Slog.i(LOG_TAG, "Read roles.xml successfully");
+        } catch (FileNotFoundException e) {
+            Slog.i(LOG_TAG, "roles.xml not found");
+        } catch (XmlPullParserException | IOException e) {
+            throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
         }
     }
 
@@ -590,7 +545,7 @@
                 throw new IllegalStateException("This RoleUserState has already been destroyed");
             }
             mWriteHandler.removeCallbacksAndMessages(null);
-            getFile(mUserId).delete();
+            mPersistence.delete(UserHandle.of(mUserId));
             mDestroyed = true;
         }
     }
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java
index 12f9fd9..1ed97be 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareService.java
@@ -257,10 +257,10 @@
         switch (status) {
             case PermissionChecker.PERMISSION_GRANTED:
                 return;
-            case PermissionChecker.PERMISSION_DENIED:
+            case PermissionChecker.PERMISSION_HARD_DENIED:
                 throw new SecurityException(
                         String.format("Caller must have the %s permission.", permission));
-            case PermissionChecker.PERMISSION_DENIED_APP_OP:
+            case PermissionChecker.PERMISSION_SOFT_DENIED:
                 throw new ServiceSpecificException(Status.TEMPORARY_PERMISSION_DENIED,
                         String.format("Caller must have the %s permission.", permission));
             default:
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 3bc860a..b11ec6f 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -168,12 +168,12 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.MissingResourceException;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -199,9 +199,16 @@
     private final Object mThermalLock = new Object();
     @GuardedBy("mThermalLock")
     private IThermalService mThermalService;
+    private final Object mStoragedLock = new Object();
+    @GuardedBy("mStoragedLock")
+    private IStoraged mStorageService;
+    private final Object mNotificationStatsLock = new Object();
+    @GuardedBy("mNotificationStatsLock")
+    private INotificationManager mNotificationManagerService;
 
     private final Context mContext;
     private StatsManager mStatsManager;
+    private StorageManager mStorageManager;
 
     public StatsPullAtomService(Context context) {
         super(context);
@@ -213,6 +220,7 @@
         mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
 
         // Used to initialize the CPU Frequency atom.
         PowerProfile powerProfile = new PowerProfile(mContext);
@@ -225,6 +233,10 @@
                     numSpeedSteps);
             firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
         }
+
+        // Used for CPU_TIME_PER_THREAD_FREQ
+        mKernelCpuThreadReader =
+                KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
     }
 
     @Override
@@ -292,7 +304,6 @@
         registerDebugFailingElapsedClock();
         registerBuildInformation();
         registerRoleHolder();
-        registerDangerousPermissionState();
         registerTimeZoneDataInfo();
         registerExternalStorageInfo();
         registerAppsOnExternalStorageInfo();
@@ -347,16 +358,61 @@
             return mThermalService;
         }
     }
+
+    private IStoraged getIStoragedService() {
+        synchronized (mStoragedLock) {
+            if (mStorageService == null) {
+                mStorageService = IStoraged.Stub.asInterface(
+                        ServiceManager.getService("storaged"));
+            }
+            if (mStorageService != null) {
+                try {
+                    mStorageService.asBinder().linkToDeath(() -> {
+                        synchronized (mStoragedLock) {
+                            mStorageService = null;
+                        }
+                    }, /* flags */ 0);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "linkToDeath with storagedService failed", e);
+                    mStorageService = null;
+                }
+            }
+        }
+        return mStorageService;
+    }
+
+    private INotificationManager getINotificationManagerService() {
+        synchronized (mNotificationStatsLock) {
+            if (mNotificationManagerService == null) {
+                mNotificationManagerService = INotificationManager.Stub.asInterface(
+                                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+            }
+            if (mNotificationManagerService != null) {
+                try {
+                    mNotificationManagerService.asBinder().linkToDeath(() -> {
+                        synchronized (mNotificationStatsLock) {
+                            mNotificationManagerService = null;
+                        }
+                    }, /* flags */ 0);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "linkToDeath with notificationManager failed", e);
+                    mNotificationManagerService = null;
+                }
+            }
+        }
+        return mNotificationManagerService;
+    }
+
     private void registerWifiBytesTransfer() {
         int tagId = StatsLog.WIFI_BYTES_TRANSFER;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {2, 3, 4, 5})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullWifiBytesTransfer(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullWifiBytesTransfer(atomTag, data)
         );
     }
 
@@ -441,14 +497,14 @@
 
     private void registerWifiBytesTransferBackground() {
         int tagId = StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {3, 4, 5, 6})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullWifiBytesTransferBackground(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullWifiBytesTransferBackground(atomTag, data)
         );
     }
 
@@ -479,14 +535,14 @@
 
     private void registerMobileBytesTransfer() {
         int tagId = StatsLog.MOBILE_BYTES_TRANSFER;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {2, 3, 4, 5})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullMobileBytesTransfer(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullMobileBytesTransfer(atomTag, data)
         );
     }
 
@@ -517,14 +573,14 @@
 
     private void registerMobileBytesTransferBackground() {
         int tagId = StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {3, 4, 5, 6})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullMobileBytesTransferBackground(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullMobileBytesTransferBackground(atomTag, data)
         );
     }
 
@@ -555,14 +611,14 @@
 
     private void registerBluetoothBytesTransfer() {
         int tagId = StatsLog.BLUETOOTH_BYTES_TRANSFER;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {2, 3})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullBluetoothBytesTransfer(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullBluetoothBytesTransfer(atomTag, data)
         );
     }
 
@@ -634,8 +690,8 @@
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 /* PullAtomMetadata */ null,
-                (atomTag, data) -> pullKernelWakelock(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullKernelWakelock(atomTag, data)
         );
     }
 
@@ -670,14 +726,14 @@
 
     private void registerCpuTimePerFreq() {
         int tagId = StatsLog.CPU_TIME_PER_FREQ;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {3})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullCpuTimePerFreq(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullCpuTimePerFreq(atomTag, data)
         );
     }
 
@@ -701,14 +757,14 @@
 
     private void registerCpuTimePerUid() {
         int tagId = StatsLog.CPU_TIME_PER_UID;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {2, 3})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullCpuTimePerUid(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullCpuTimePerUid(atomTag, data)
         );
     }
 
@@ -730,14 +786,14 @@
         // the throttling is 3sec, handled in
         // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
         int tagId = StatsLog.CPU_TIME_PER_UID_FREQ;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {4})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullCpuTimeperUidFreq(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullCpuTimeperUidFreq(atomTag, data)
         );
     }
 
@@ -762,14 +818,14 @@
         // the throttling is 3sec, handled in
         // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
         int tagId = StatsLog.CPU_ACTIVE_TIME;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {2})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullCpuActiveTime(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullCpuActiveTime(atomTag, data)
         );
     }
 
@@ -789,14 +845,14 @@
         // the throttling is 3sec, handled in
         // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
         int tagId = StatsLog.CPU_CLUSTER_TIME;
-        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
                 .setAdditiveFields(new int[] {3})
                 .build();
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 metadata,
-                (atomTag, data) -> pullCpuClusterTime(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullCpuClusterTime(atomTag, data)
         );
     }
 
@@ -913,8 +969,8 @@
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 /* metadata */ null,
-                (atomTag, data) -> pullBluetoothActivityInfo(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullBluetoothActivityInfo(atomTag, data)
         );
     }
 
@@ -936,12 +992,29 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private static final long NS_PER_SEC = 1000000000;
+
     private void registerSystemElapsedRealtime() {
-        // No op.
+        int tagId = StatsLog.SYSTEM_ELAPSED_REALTIME;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setCoolDownNs(NS_PER_SEC)
+                .setTimeoutNs(NS_PER_SEC / 2)
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullSystemElapsedRealtime(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullSystemElapsedRealtime() {
-        // No op.
+    private int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) {
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeLong(SystemClock.elapsedRealtime())
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerSystemUptime() {
@@ -949,8 +1022,8 @@
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 null, // use default PullAtomMetadata values
-                (atomTag, data) -> pullSystemUptime(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullSystemUptime(atomTag, data)
         );
     }
 
@@ -1232,8 +1305,8 @@
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 /* PullAtomMetadata */ null,
-                (atomTag, data) -> pullIonHeapSize(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullIonHeapSize(atomTag, data)
         );
     }
 
@@ -1427,59 +1500,372 @@
     }
 
     private void registerLooperStats() {
-        // No op.
+        int tagId = StatsLog.LOOPER_STATS;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullLooperStats(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullLooperStats() {
-        // No op.
+    private int pullLooperStats(int atomTag, List<StatsEvent> pulledData) {
+        LooperStats looperStats = LocalServices.getService(LooperStats.class);
+        if (looperStats == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+        looperStats.reset();
+        for (LooperStats.ExportedEntry entry : entries) {
+            StatsEvent e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(entry.workSourceUid)
+                    .writeString(entry.handlerClassName)
+                    .writeString(entry.threadName)
+                    .writeString(entry.messageName)
+                    .writeLong(entry.messageCount)
+                    .writeLong(entry.exceptionCount)
+                    .writeLong(entry.recordedMessageCount)
+                    .writeLong(entry.totalLatencyMicros)
+                    .writeLong(entry.cpuUsageMicros)
+                    .writeBoolean(entry.isInteractive)
+                    .writeLong(entry.maxCpuUsageMicros)
+                    .writeLong(entry.maxLatencyMicros)
+                    .writeLong(entry.recordedDelayMessageCount)
+                    .writeLong(entry.delayMillis)
+                    .writeLong(entry.maxDelayMillis)
+                    .build();
+            pulledData.add(e);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDiskStats() {
-        // No op.
+        int tagId = StatsLog.DISK_STATS;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDiskStats(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDiskStats() {
-        // No op.
+    private int pullDiskStats(int atomTag, List<StatsEvent> pulledData) {
+        // Run a quick-and-dirty performance test: write 512 bytes
+        byte[] junk = new byte[512];
+        for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
+
+        File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
+        FileOutputStream fos = null;
+        IOException error = null;
+
+        long before = SystemClock.elapsedRealtime();
+        try {
+            fos = new FileOutputStream(tmp);
+            fos.write(junk);
+        } catch (IOException e) {
+            error = e;
+        } finally {
+            try {
+                if (fos != null) fos.close();
+            } catch (IOException e) {
+                // Do nothing.
+            }
+        }
+
+        long latency = SystemClock.elapsedRealtime() - before;
+        if (tmp.exists()) tmp.delete();
+
+        if (error != null) {
+            Slog.e(TAG, "Error performing diskstats latency test");
+            latency = -1;
+        }
+        // File based encryption.
+        boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
+
+        //Recent disk write speed. Binder call to storaged.
+        int writeSpeed = -1;
+        IStoraged storaged = getIStoragedService();
+        if (storaged == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        try {
+            writeSpeed = storaged.getRecentPerf();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "storaged not found");
+        }
+
+        // Add info pulledData.
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeLong(latency)
+                .writeBoolean(fileBased)
+                .writeInt(writeSpeed)
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDirectoryUsage() {
-        // No op.
+        int tagId = StatsLog.DIRECTORY_USAGE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDirectoryUsage(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDirectoryUsage() {
-        // No op.
+    private int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) {
+        StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
+        StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
+        StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
+
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
+                .writeLong(statFsData.getAvailableBytes())
+                .writeLong(statFsData.getTotalBytes())
+                .build();
+        pulledData.add(e);
+
+        e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
+                .writeLong(statFsCache.getAvailableBytes())
+                .writeLong(statFsCache.getTotalBytes())
+                .build();
+        pulledData.add(e);
+
+        e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
+                .writeLong(statFsSystem.getAvailableBytes())
+                .writeLong(statFsSystem.getTotalBytes())
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerAppSize() {
-        // No op.
+        int tagId = StatsLog.APP_SIZE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullAppSize(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullAppSize() {
-        // No op.
+    private int pullAppSize(int atomTag, List<StatsEvent> pulledData) {
+        try {
+            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
+            JSONObject json = new JSONObject(jsonStr);
+            long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
+            JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
+            JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
+            JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
+            JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
+            // Sanity check: Ensure all 4 lists have the same length.
+            int length = pkg_names.length();
+            if (app_sizes.length() != length || app_data_sizes.length() != length
+                    || app_cache_sizes.length() != length) {
+                Slog.e(TAG, "formatting error in diskstats cache file!");
+                return StatsManager.PULL_SKIP;
+            }
+            for (int i = 0; i < length; i++) {
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeString(pkg_names.getString(i))
+                        .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
+                        .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
+                        .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
+                        .writeLong(cache_time)
+                        .build();
+                pulledData.add(e);
+            }
+        } catch (IOException | JSONException e) {
+            Slog.e(TAG, "exception reading diskstats cache file", e);
+            return StatsManager.PULL_SKIP;
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerCategorySize() {
-        // No op.
+        int tagId = StatsLog.CATEGORY_SIZE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullCategorySize(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullCategorySize() {
-        // No op.
+    private int pullCategorySize(int atomTag, List<StatsEvent> pulledData) {
+        try {
+            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
+            JSONObject json = new JSONObject(jsonStr);
+            long cacheTime = json.optLong(
+                    DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
+
+            StatsEvent e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
+                    .writeLong(
+                            json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
+                    .writeLong(
+                            json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+        } catch (IOException | JSONException e) {
+            Slog.e(TAG, "exception reading diskstats cache file", e);
+            return StatsManager.PULL_SKIP;
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerNumFingerprintsEnrolled() {
-        // No op.
-    }
-
-    private void pullNumFingerprintsEnrolled() {
-        // No op.
+        int tagId = StatsLog.NUM_FINGERPRINTS_ENROLLED;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullNumBiometricsEnrolled(
+                        BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
     private void registerNumFacesEnrolled() {
-        // No op.
+        int tagId = StatsLog.NUM_FACES_ENROLLED;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullNumBiometricsEnrolled(
+                        BiometricsProtoEnums.MODALITY_FACE, atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullNumFacesEnrolled() {
-        // No op.
+    private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) {
+        final PackageManager pm = mContext.getPackageManager();
+        FingerprintManager fingerprintManager = null;
+        FaceManager faceManager = null;
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+            fingerprintManager = mContext.getSystemService(FingerprintManager.class);
+        }
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+            faceManager = mContext.getSystemService(FaceManager.class);
+        }
+
+        if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        UserManager userManager = mContext.getSystemService(UserManager.class);
+        if (userManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            for (UserInfo user : userManager.getUsers()) {
+                final int userId = user.getUserHandle().getIdentifier();
+                int numEnrolled = 0;
+                if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
+                    numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
+                } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
+                    numEnrolled = faceManager.getEnrolledFaces(userId).size();
+                } else {
+                    return StatsManager.PULL_SKIP;
+                }
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(userId)
+                        .writeInt(numEnrolled)
+                        .build();
+                pulledData.add(e);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerProcStats() {
@@ -1498,12 +1884,44 @@
         // No op.
     }
 
+    private StoragedUidIoStatsReader mStoragedUidIoStatsReader =
+            new StoragedUidIoStatsReader();
+
     private void registerDiskIO() {
-        // No op.
+        int tagId = StatsLog.DISK_IO;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
+                .setCoolDownNs(3 * NS_PER_SEC)
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullDiskIO(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDiskIO() {
-        // No op.
+    private int pullDiskIO(int atomTag, List<StatsEvent> pulledData) {
+        mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
+                fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
+                fgFsync, bgFsync) -> {
+            StatsEvent e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(uid)
+                    .writeLong(fgCharsRead)
+                    .writeLong(fgCharsWrite)
+                    .writeLong(fgBytesRead)
+                    .writeLong(fgBytesWrite)
+                    .writeLong(bgCharsRead)
+                    .writeLong(bgCharsWrite)
+                    .writeLong(bgBytesRead)
+                    .writeLong(bgBytesWrite)
+                    .writeLong(fgFsync)
+                    .writeLong(bgFsync)
+                    .build();
+            pulledData.add(e);
+        });
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerPowerProfile() {
@@ -1511,8 +1929,8 @@
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 /* PullAtomMetadata */ null,
-                (atomTag, data) -> pullPowerProfile(atomTag, data),
-                Executors.newSingleThreadExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullPowerProfile(atomTag, data)
         );
     }
 
@@ -1529,20 +1947,118 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private final Object mCpuTrackerLock = new Object();
+    @GuardedBy("mCpuTrackerLock")
+    private ProcessCpuTracker mProcessCpuTracker;
+
     private void registerProcessCpuTime() {
-        // No op.
+        int tagId = StatsLog.PROCESS_CPU_TIME;
+        // Min cool-down is 5 sec, inline with what ActivityManagerService uses.
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setCoolDownNs(5 * NS_PER_SEC)
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullProcessCpuTime(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullProcessCpuTime() {
-        // No op.
+    private int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) {
+        synchronized (mCpuTrackerLock) {
+            if (mProcessCpuTracker == null) {
+                mProcessCpuTracker = new ProcessCpuTracker(false);
+                mProcessCpuTracker.init();
+            }
+            mProcessCpuTracker.update();
+            for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
+                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(st.uid)
+                        .writeString(st.name)
+                        .writeLong(st.base_utime)
+                        .writeLong(st.base_stime)
+                        .build();
+                pulledData.add(e);
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
+    @Nullable
+    private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
+    private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
+
     private void registerCpuTimePerThreadFreq() {
-        // No op.
+        int tagId = StatsLog.CPU_TIME_PER_THREAD_FREQ;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullCpuTimePerThreadFreq(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullCpuTimePerThreadFreq() {
-        // No op.
+    private int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) {
+        if (this.mKernelCpuThreadReader == null) {
+            Slog.e(TAG, "mKernelCpuThreadReader is null");
+            return StatsManager.PULL_SKIP;
+        }
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
+                this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
+        if (processCpuUsages == null) {
+            Slog.e(TAG, "processCpuUsages is null");
+            return StatsManager.PULL_SKIP;
+        }
+        int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
+        if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
+            String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
+                    + " frequencies, but got " + cpuFrequencies.length;
+            Slog.w(TAG, message);
+            return StatsManager.PULL_SKIP;
+        }
+        for (int i = 0; i < processCpuUsages.size(); i++) {
+            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
+            ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
+                    processCpuUsage.threadCpuUsages;
+            for (int j = 0; j < threadCpuUsages.size(); j++) {
+                KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
+                if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
+                    String message = "Unexpected number of usage times,"
+                            + " expected " + cpuFrequencies.length
+                            + " but got " + threadCpuUsage.usageTimesMillis.length;
+                    Slog.w(TAG, message);
+                    return StatsManager.PULL_SKIP;
+                }
+
+                StatsEvent.Builder e = StatsEvent.newBuilder();
+                e.setAtomId(atomTag);
+                e.writeInt(processCpuUsage.uid);
+                e.writeInt(processCpuUsage.processId);
+                e.writeInt(threadCpuUsage.threadId);
+                e.writeString(processCpuUsage.processName);
+                e.writeString(threadCpuUsage.threadName);
+                for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
+                    if (k < cpuFrequencies.length) {
+                        e.writeInt(cpuFrequencies[k]);
+                        e.writeInt(threadCpuUsage.usageTimesMillis[k]);
+                    } else {
+                        // If we have no more frequencies to write, we still must write empty data.
+                        // We know that this data is empty (and not just zero) because all
+                        // frequencies are expected to be greater than zero
+                        e.writeInt(0);
+                        e.writeInt(0);
+                    }
+                }
+                pulledData.add(e.build());
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     // TODO: move to top of file when all migrations are complete
@@ -1681,8 +2197,8 @@
         mStatsManager.registerPullAtomCallback(
                 tagId,
                 null, // use default PullAtomMetadata values
-                (atomTag, data) -> pullBuildInformation(atomTag, data),
-                BackgroundThread.getExecutor()
+                BackgroundThread.getExecutor(),
+                (atomTag, data) -> pullBuildInformation(atomTag, data)
         );
     }
 
@@ -1704,43 +2220,280 @@
     }
 
     private void registerRoleHolder() {
-        // No op.
+        int tagId = StatsLog.ROLE_HOLDER;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullRoleHolder(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullRoleHolder() {
-        // No op.
+    // Add a RoleHolder atom for each package that holds a role.
+    private int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) {
+        long callingToken = Binder.clearCallingIdentity();
+        try {
+            PackageManager pm = mContext.getPackageManager();
+            RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
+
+            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+            int numUsers = users.size();
+            for (int userNum = 0; userNum < numUsers; userNum++) {
+                int userId = users.get(userNum).getUserHandle().getIdentifier();
+
+                ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
+
+                int numRoles = roles.size();
+                for (int roleNum = 0; roleNum < numRoles; roleNum++) {
+                    String roleName = roles.keyAt(roleNum);
+                    ArraySet<String> holders = roles.valueAt(roleNum);
+
+                    int numHolders = holders.size();
+                    for (int holderNum = 0; holderNum < numHolders; holderNum++) {
+                        String holderName = holders.valueAt(holderNum);
+
+                        PackageInfo pkg;
+                        try {
+                            pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
+                        } catch (PackageManager.NameNotFoundException e) {
+                            Slog.w(TAG, "Role holder " + holderName + " not found");
+                            return StatsManager.PULL_SKIP;
+                        }
+
+                        StatsEvent e = StatsEvent.newBuilder()
+                                .setAtomId(atomTag)
+                                .writeInt(pkg.applicationInfo.uid)
+                                .writeString(holderName)
+                                .writeString(roleName)
+                                .build();
+                        pulledData.add(e);
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDangerousPermissionState() {
-        // No op.
+        int tagId = StatsLog.DANGEROUS_PERMISSION_STATE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDangerousPermissionState(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDangerousPermissionState() {
-        // No op.
+    private int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) {
+        final long token = Binder.clearCallingIdentity();
+        Set<Integer> reportedUids = new HashSet<>();
+        try {
+            PackageManager pm = mContext.getPackageManager();
+
+            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+            int numUsers = users.size();
+            for (int userNum = 0; userNum < numUsers; userNum++) {
+                UserHandle user = users.get(userNum).getUserHandle();
+
+                List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
+                        PackageManager.GET_PERMISSIONS, user.getIdentifier());
+
+                int numPkgs = pkgs.size();
+                for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
+                    PackageInfo pkg = pkgs.get(pkgNum);
+
+                    if (pkg.requestedPermissions == null) {
+                        continue;
+                    }
+
+                    if (reportedUids.contains(pkg.applicationInfo.uid)) {
+                        // do not report same uid twice
+                        continue;
+                    }
+                    reportedUids.add(pkg.applicationInfo.uid);
+
+                    if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
+                            && ThreadLocalRandom.current().nextFloat() > 0.2f) {
+                        continue;
+                    }
+
+                    int numPerms = pkg.requestedPermissions.length;
+                    for (int permNum  = 0; permNum < numPerms; permNum++) {
+                        String permName = pkg.requestedPermissions[permNum];
+
+                        PermissionInfo permissionInfo;
+                        int permissionFlags = 0;
+                        try {
+                            permissionInfo = pm.getPermissionInfo(permName, 0);
+                            permissionFlags =
+                                    pm.getPermissionFlags(permName, pkg.packageName, user);
+                        } catch (PackageManager.NameNotFoundException ignored) {
+                            continue;
+                        }
+
+                        if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
+                            continue;
+                        }
+
+                        StatsEvent.Builder e = StatsEvent.newBuilder();
+                        e.setAtomId(atomTag);
+                        e.writeString(permName);
+                        e.writeInt(pkg.applicationInfo.uid);
+                        if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE) {
+                            e.writeString("");
+                        }
+                        e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
+                                & REQUESTED_PERMISSION_GRANTED) != 0);
+                        e.writeInt(permissionFlags);
+
+                        pulledData.add(e.build());
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            Log.e(TAG, "Could not read permissions", t);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerTimeZoneDataInfo() {
-        // No op.
+        int tagId = StatsLog.TIME_ZONE_DATA_INFO;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullTimeZoneDataInfo(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullTimeZoneDataInfo() {
-        // No op.
+    private int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) {
+        String tzDbVersion = "Unknown";
+        try {
+            tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
+        } catch (MissingResourceException e) {
+            Slog.e(TAG, "Getting tzdb version failed: ", e);
+            return StatsManager.PULL_SKIP;
+        }
+
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeString(tzDbVersion)
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerExternalStorageInfo() {
-        // No op.
+        int tagId = StatsLog.EXTERNAL_STORAGE_INFO;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullExternalStorageInfo(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullExternalStorageInfo() {
-        // No op.
+    private int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+        if (mStorageManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        List<VolumeInfo> volumes = mStorageManager.getVolumes();
+        for (VolumeInfo vol : volumes) {
+            final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
+            final DiskInfo diskInfo = vol.getDisk();
+            if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
+                // Get the type of the volume, if it is adoptable or portable.
+                int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
+                if (vol.getType() == TYPE_PUBLIC) {
+                    volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
+                } else if (vol.getType() == TYPE_PRIVATE) {
+                    volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
+                }
+
+                // Get the type of external storage inserted in the device (sd cards, usb, etc.)
+                int externalStorageType;
+                if (diskInfo.isSd()) {
+                    externalStorageType = StorageEnums.SD_CARD;
+                } else if (diskInfo.isUsb()) {
+                    externalStorageType = StorageEnums.USB;
+                } else {
+                    externalStorageType = StorageEnums.OTHER;
+                }
+
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(externalStorageType)
+                        .writeInt(volumeType)
+                        .writeLong(diskInfo.size)
+                        .build();
+                pulledData.add(e);
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerAppsOnExternalStorageInfo() {
-        // No op.
+        int tagId = StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullAppsOnExternalStorageInfo(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullAppsOnExternalStorageInfo() {
-        // No op.
+    private int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+        if (mStorageManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        PackageManager pm = mContext.getPackageManager();
+        List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
+        for (ApplicationInfo appInfo : apps) {
+            UUID storageUuid = appInfo.storageUuid;
+            if (storageUuid == null) {
+                continue;
+            }
+
+            VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
+                    appInfo.storageUuid.toString());
+            if (volumeInfo == null) {
+                continue;
+            }
+
+            DiskInfo diskInfo = volumeInfo.getDisk();
+            if (diskInfo == null) {
+                continue;
+            }
+
+            int externalStorageType = -1;
+            if (diskInfo.isSd()) {
+                externalStorageType = StorageEnums.SD_CARD;
+            } else if (diskInfo.isUsb()) {
+                externalStorageType = StorageEnums.USB;
+            } else if (appInfo.isExternal()) {
+                externalStorageType = StorageEnums.OTHER;
+            }
+
+            // App is installed on external storage.
+            if (externalStorageType != -1) {
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(externalStorageType)
+                        .writeString(appInfo.packageName)
+                        .build();
+                pulledData.add(e);
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerFaceSettings() {
@@ -1752,26 +2505,167 @@
     }
 
     private void registerAppOps() {
-        // No op.
+        int tagId = StatsLog.APP_OPS;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullAppOps(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
+
     }
 
-    private void pullAppOps() {
-        // No op.
+    private int pullAppOps(int atomTag, List<StatsEvent> pulledData) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+
+            CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
+            HistoricalOpsRequest histOpsRequest =
+                    new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).build();
+            appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
+
+            HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
+                    TimeUnit.MILLISECONDS);
+
+            for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
+                final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
+                final int uid = uidOps.getUid();
+                for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
+                    final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
+                    for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
+                        final AppOpsManager.HistoricalOp op  = packageOps.getOpAt(opIdx);
+
+                        StatsEvent.Builder e = StatsEvent.newBuilder();
+                        e.setAtomId(atomTag);
+                        e.writeInt(uid);
+                        e.writeString(packageOps.getPackageName());
+                        e.writeInt(op.getOpCode());
+                        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+
+                        String perm = AppOpsManager.opToPermission(op.getOpCode());
+                        if (perm == null) {
+                            e.writeBoolean(false);
+                        } else {
+                            PermissionInfo permInfo;
+                            try {
+                                permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
+                                e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
+                            } catch (PackageManager.NameNotFoundException exception) {
+                                e.writeBoolean(false);
+                            }
+                        }
+
+                        pulledData.add(e.build());
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            // TODO: catch exceptions at a more granular level
+            Slog.e(TAG, "Could not read appops", t);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
+            List<ParcelFileDescriptor> statsFiles) throws IOException {
+        InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
+        int[] len = new int[1];
+        byte[] stats = readFully(stream, len);
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeByteArray(Arrays.copyOf(stats, len[0]))
+                .build();
+        pulledData.add(e);
+    }
+
+    static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
+        int pos = 0;
+        final int initialAvail = stream.available();
+        byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
+        while (true) {
+            int amt = stream.read(data, pos, data.length - pos);
+            if (DEBUG) {
+                Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
+            }
+            if (amt < 0) {
+                if (DEBUG) {
+                    Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
+                }
+                outLen[0] = pos;
+                return data;
+            }
+            pos += amt;
+            if (pos >= data.length) {
+                byte[] newData = new byte[pos + 16384];
+                if (DEBUG) {
+                    Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
+                }
+                System.arraycopy(data, 0, newData, 0, pos);
+                data = newData;
+            }
+        }
     }
 
     private void registerNotificationRemoteViews() {
-        // No op.
+        int tagId = StatsLog.NOTIFICATION_REMOTE_VIEWS;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullNotificationRemoteViews(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullNotificationRemoteViews() {
-        // No op.
+    private int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) {
+        INotificationManager notificationManagerService = getINotificationManagerService();
+        if (notificationManagerService == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        final long callingToken = Binder.clearCallingIdentity();
+        try {
+            // determine last pull tine. Copy file trick from pullProcessStats?
+            long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
+            long lastNotificationStatsNs = wallClockNanos -
+                    TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
+
+            List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
+            notificationManagerService.pullStats(lastNotificationStatsNs,
+                    NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
+            if (statsFiles.size() != 1) {
+                return StatsManager.PULL_SKIP;
+            }
+            unpackStreamedData(atomTag, pulledData, statsFiles);
+        } catch (IOException e) {
+            Slog.e(TAG, "Getting notistats failed: ", e);
+            return StatsManager.PULL_SKIP;
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Getting notistats failed: ", e);
+            return StatsManager.PULL_SKIP;
+        } catch (SecurityException e) {
+            Slog.e(TAG, "Getting notistats failed: ", e);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDangerousPermissionStateSampled() {
-        // No op.
-    }
-
-    private void pullDangerousPermissionStateSampled() {
-        // No op.
+        int tagId = StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDangerousPermissionState(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 }
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 5283cc4..3dee853 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -25,6 +25,7 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
@@ -53,6 +54,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FunctionalUtils;
+import com.android.internal.util.FunctionalUtils.ThrowingConsumer;
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
@@ -74,6 +76,19 @@
 
     private static final String LOG_TAG = "TextClassificationManagerService";
 
+    private static final ITextClassifierCallback NO_OP_CALLBACK = new ITextClassifierCallback() {
+        @Override
+        public void onSuccess(Bundle result) {}
+
+        @Override
+        public void onFailure() {}
+
+        @Override
+        public IBinder asBinder() {
+            return null;
+        }
+    };
+
     public static final class Lifecycle extends SystemService {
 
         private final TextClassificationManagerService mManagerService;
@@ -158,28 +173,14 @@
             TextSelection.Request request, ITextClassifierCallback callback)
             throws RemoteException {
         Objects.requireNonNull(request);
-        Objects.requireNonNull(callback);
-        final int userId = request.getUserId();
-        validateInput(mContext, request.getCallingPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (!userState.bindLocked()) {
-                Slog.d(LOG_TAG, "Unable to bind TextClassifierService at suggestSelection.");
-                callback.onFailure();
-            } else if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "suggestSelection")) {
-                    return;
-                }
-                userState.mService.onSuggestSelection(sessionId, request, callback);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("suggestSelection",
-                        () -> userState.mService.onSuggestSelection(sessionId, request, callback),
-                        callback::onFailure, callback.asBinder(), this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                request.getUserId(),
+                request.getCallingPackageName(),
+                /* attemptToBind= */ true,
+                service -> service.onSuggestSelection(sessionId, request, callback),
+                "onSuggestSelection",
+                callback);
     }
 
     @Override
@@ -188,27 +189,14 @@
             TextClassification.Request request, ITextClassifierCallback callback)
             throws RemoteException {
         Objects.requireNonNull(request);
-        Objects.requireNonNull(callback);
-        final int userId = request.getUserId();
-        validateInput(mContext, request.getCallingPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (!userState.bindLocked()) {
-                Slog.d(LOG_TAG, "Unable to bind TextClassifierService at classifyText.");
-                callback.onFailure();
-            } else if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(), "classifyText")) {
-                    return;
-                }
-                userState.mService.onClassifyText(sessionId, request, callback);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("classifyText",
-                        () -> userState.mService.onClassifyText(sessionId, request, callback),
-                        callback::onFailure, callback.asBinder(), this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                request.getUserId(),
+                request.getCallingPackageName(),
+                /* attemptToBind= */ true,
+                service -> service.onClassifyText(sessionId, request, callback),
+                "onClassifyText",
+                callback);
     }
 
     @Override
@@ -217,28 +205,14 @@
             TextLinks.Request request, ITextClassifierCallback callback)
             throws RemoteException {
         Objects.requireNonNull(request);
-        Objects.requireNonNull(callback);
-        final int userId = request.getUserId();
-        validateInput(mContext, request.getCallingPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (!userState.bindLocked()) {
-                Slog.d(LOG_TAG, "Unable to bind TextClassifierService at generateLinks.");
-                callback.onFailure();
-            } else if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "generateLinks")) {
-                    return;
-                }
-                userState.mService.onGenerateLinks(sessionId, request, callback);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("generateLinks",
-                        () -> userState.mService.onGenerateLinks(sessionId, request, callback),
-                        callback::onFailure, callback.asBinder(), this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                request.getUserId(),
+                request.getCallingPackageName(),
+                /* attemptToBind= */ true,
+                service -> service.onGenerateLinks(sessionId, request, callback),
+                "onGenerateLinks",
+                callback);
     }
 
     @Override
@@ -246,53 +220,34 @@
             @Nullable TextClassificationSessionId sessionId, SelectionEvent event)
             throws RemoteException {
         Objects.requireNonNull(event);
-        final int userId = event.getUserId();
-        validateInput(mContext, event.getPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "selectionEvent")) {
-                    return;
-                }
-                userState.mService.onSelectionEvent(sessionId, event);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("selectionEvent",
-                        () -> userState.mService.onSelectionEvent(sessionId, event),
-                        null /* onServiceFailure */, null /* binder */, this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                event.getUserId(),
+                event.getPackageName(),
+                /* attemptToBind= */ false,
+                service -> service.onSelectionEvent(sessionId, event),
+                "onSelectionEvent",
+                NO_OP_CALLBACK);
     }
     @Override
     public void onTextClassifierEvent(
             @Nullable TextClassificationSessionId sessionId,
             TextClassifierEvent event) throws RemoteException {
         Objects.requireNonNull(event);
+
         final String packageName = event.getEventContext() == null
                 ? null
                 : event.getEventContext().getPackageName();
         final int userId = event.getEventContext() == null
                 ? UserHandle.getCallingUserId()
                 : event.getEventContext().getUserId();
-        validateInput(mContext, packageName, userId);
-
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "textClassifierEvent")) {
-                    return;
-                }
-                userState.mService.onTextClassifierEvent(sessionId, event);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("textClassifierEvent",
-                        () -> userState.mService.onTextClassifierEvent(sessionId, event),
-                        null /* onServiceFailure */, null /* binder */, this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                userId,
+                packageName,
+                /* attemptToBind= */ false,
+                service -> service.onTextClassifierEvent(sessionId, event),
+                "onTextClassifierEvent",
+                NO_OP_CALLBACK);
     }
 
     @Override
@@ -301,28 +256,14 @@
             TextLanguage.Request request,
             ITextClassifierCallback callback) throws RemoteException {
         Objects.requireNonNull(request);
-        Objects.requireNonNull(callback);
-        final int userId = request.getUserId();
-        validateInput(mContext, request.getCallingPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (!userState.bindLocked()) {
-                Slog.d(LOG_TAG, "Unable to bind TextClassifierService at detectLanguage.");
-                callback.onFailure();
-            } else if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "detectLanguage")) {
-                    return;
-                }
-                userState.mService.onDetectLanguage(sessionId, request, callback);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("detectLanguage",
-                        () -> userState.mService.onDetectLanguage(sessionId, request, callback),
-                        callback::onFailure, callback.asBinder(), this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                request.getUserId(),
+                request.getCallingPackageName(),
+                /* attemptToBind= */ true,
+                service -> service.onDetectLanguage(sessionId, request, callback),
+                "onDetectLanguage",
+                callback);
     }
 
     @Override
@@ -331,30 +272,14 @@
             ConversationActions.Request request,
             ITextClassifierCallback callback) throws RemoteException {
         Objects.requireNonNull(request);
-        Objects.requireNonNull(callback);
-        final int userId = request.getUserId();
-        validateInput(mContext, request.getCallingPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (!userState.bindLocked()) {
-                Slog.d(LOG_TAG,
-                        "Unable to bind TextClassifierService at suggestConversationActions.");
-                callback.onFailure();
-            } else if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "suggestConversationActions")) {
-                    return;
-                }
-                userState.mService.onSuggestConversationActions(sessionId, request, callback);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("suggestConversationActions",
-                        () -> userState.mService.onSuggestConversationActions(sessionId, request,
-                                callback),
-                        callback::onFailure, callback.asBinder(), this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        handleRequest(
+                request.getUserId(),
+                request.getCallingPackageName(),
+                /* attemptToBind= */ true,
+                service -> service.onSuggestConversationActions(sessionId, request, callback),
+                "onSuggestConversationActions",
+                callback);
     }
 
     @Override
@@ -363,30 +288,18 @@
             throws RemoteException {
         Objects.requireNonNull(sessionId);
         Objects.requireNonNull(classificationContext);
-        final int userId = classificationContext.getUserId();
-        validateInput(mContext, classificationContext.getPackageName(), userId);
 
-        synchronized (mLock) {
-            UserState userState = getUserStateLocked(userId);
-            if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "createTextClassificationSession")) {
-                    return;
-                }
-                userState.mService.onCreateTextClassificationSession(
-                        classificationContext, sessionId);
-                mSessionUserIds.put(sessionId, userId);
-            } else {
-                userState.mPendingRequests.add(new PendingRequest("createTextClassificationSession",
-                        () -> {
-                            userState.mService.onCreateTextClassificationSession(
-                                    classificationContext, sessionId);
-                            mSessionUserIds.put(sessionId, userId);
-                        },
-                        null /* onServiceFailure */, null /* binder */, this, userState,
-                        Binder.getCallingUid()));
-            }
-        }
+        final int userId = classificationContext.getUserId();
+        handleRequest(
+                userId,
+                classificationContext.getPackageName(),
+                /* attemptToBind= */ false,
+                service -> {
+                    service.onCreateTextClassificationSession(classificationContext, sessionId);
+                    mSessionUserIds.put(sessionId, userId);
+                },
+                "onCreateTextClassificationSession",
+                NO_OP_CALLBACK);
     }
 
     @Override
@@ -398,27 +311,16 @@
             final int userId = mSessionUserIds.containsKey(sessionId)
                     ? mSessionUserIds.get(sessionId)
                     : UserHandle.getCallingUserId();
-            validateInput(mContext, null /* packageName */, userId);
-
-            UserState userState = getUserStateLocked(userId);
-            if (userState.isBoundLocked()) {
-                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(),
-                        "destroyTextClassificationSession")) {
-                    return;
-                }
-                userState.mService.onDestroyTextClassificationSession(sessionId);
-                mSessionUserIds.remove(sessionId);
-            } else {
-                userState.mPendingRequests.add(
-                        new PendingRequest("destroyTextClassificationSession",
-                                () -> {
-                                    userState.mService.onDestroyTextClassificationSession(
-                                            sessionId);
-                                    mSessionUserIds.remove(sessionId);
-                                },
-                                null /* onServiceFailure */, null /* binder */, this, userState,
-                                Binder.getCallingUid()));
-            }
+            handleRequest(
+                    userId,
+                    /* callingPackageName= */ null,
+                    /* attemptToBind= */ false,
+                    service -> {
+                        service.onDestroyTextClassificationSession(sessionId);
+                        mSessionUserIds.remove(sessionId);
+                    },
+                    "onDestroyTextClassificationSession",
+                    NO_OP_CALLBACK);
         }
     }
 
@@ -466,6 +368,42 @@
         }
     }
 
+    private void handleRequest(
+            @UserIdInt int userId,
+            @Nullable String callingPackageName,
+            boolean attemptToBind,
+            @NonNull ThrowingConsumer<ITextClassifierService> textClassifierServiceConsumer,
+            @NonNull String methodName,
+            @NonNull ITextClassifierCallback callback)
+            throws RemoteException {
+        Objects.requireNonNull(textClassifierServiceConsumer);
+        Objects.requireNonNull(methodName);
+        Objects.requireNonNull(callback);
+
+        validateInput(mContext, callingPackageName, userId);
+        synchronized (mLock) {
+            UserState userState = getUserStateLocked(userId);
+            if (attemptToBind && !userState.bindLocked()) {
+                Slog.d(LOG_TAG, "Unable to bind TextClassifierService at " + methodName);
+                callback.onFailure();
+            } else if (userState.isBoundLocked()) {
+                if (!userState.checkRequestAcceptedLocked(Binder.getCallingUid(), methodName)) {
+                    return;
+                }
+                textClassifierServiceConsumer.accept(userState.mService);
+            } else {
+                userState.mPendingRequests.add(
+                        new PendingRequest(
+                                methodName,
+                                () -> textClassifierServiceConsumer.accept(userState.mService),
+                                callback::onFailure, callback.asBinder(),
+                                this,
+                                userState,
+                                Binder.getCallingUid()));
+            }
+        }
+    }
+
     private void unbindServiceIfNecessary() {
         final ComponentName serviceComponentName =
                 TextClassifierService.getServiceComponentName(mContext);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b596d2a..0e13e6c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -745,7 +745,8 @@
             synchronized (mAtmService.mGlobalLock) {
                 Slog.w(TAG, "Activity stop timeout for " + ActivityRecord.this);
                 if (isInHistory()) {
-                    activityStopped(null /*icicle*/, null /*persistentState*/, null /*description*/);
+                    activityStopped(
+                            null /*icicle*/, null /*persistentState*/, null /*description*/);
                 }
             }
         }
@@ -1286,17 +1287,11 @@
 
         updateColorTransform();
 
-        final ActivityStack oldStack = (oldTask != null) ? oldTask.getStack() : null;
-        final ActivityStack newStack = (newTask != null) ? newTask.getStack() : null;
-        // Inform old stack (if present) of activity removal and new stack (if set) of activity
-        // addition.
-        if (oldStack != newStack) {
-            if (oldStack !=  null) {
-                oldStack.onActivityRemovedFromStack(this);
-            }
-            if (newStack !=  null) {
-                newStack.onActivityAddedToStack(this);
-            }
+        if (oldTask != null) {
+            oldTask.cleanUpActivityReferences(this);
+        }
+        if (newTask != null && isState(RESUMED)) {
+            newTask.setResumedActivity(this, "onParentChanged");
         }
     }
 
@@ -2904,8 +2899,7 @@
      * Note: Call before {@link #removeFromHistory(String)}.
      */
     void cleanUp(boolean cleanServices, boolean setState) {
-        final ActivityStack stack = getActivityStack();
-        stack.onActivityRemovedFromStack(this);
+        task.cleanUpActivityReferences(this);
 
         deferRelaunchUntilPaused = false;
         frozenBeforeDestroy = false;
@@ -4089,11 +4083,12 @@
 
     @Override
     boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
-            boolean isVoiceInteraction) {
+            boolean isVoiceInteraction, @Nullable Runnable animationFinishedCallback) {
         if (mUseTransferredAnimation) {
             return false;
         }
-        return super.applyAnimation(lp, transit, enter, isVoiceInteraction);
+        return super.applyAnimation(lp, transit, enter, isVoiceInteraction,
+                animationFinishedCallback);
     }
 
     /**
@@ -5832,7 +5827,7 @@
     @Override
     boolean isWaitingForTransitionStart() {
         final DisplayContent dc = getDisplayContent();
-        return dc.mAppTransition.isTransitionSet()
+        return dc != null && dc.mAppTransition.isTransitionSet()
                 && (dc.mOpeningApps.contains(this)
                 || dc.mClosingApps.contains(this)
                 || dc.mChangingApps.contains(this));
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index f5fba8e..60e0f51e 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -80,7 +80,6 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
@@ -119,7 +118,6 @@
 import static com.android.server.wm.StackProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import static java.lang.Integer.MAX_VALUE;
@@ -153,6 +151,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
+import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -162,7 +161,6 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.ITaskOrganizer;
-import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.GuardedBy;
@@ -190,7 +188,7 @@
 /**
  * State and management of a single stack of activities.
  */
-class ActivityStack extends WindowContainer<WindowContainer> implements BoundsAnimationTarget {
+class ActivityStack extends Task implements BoundsAnimationTarget {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM;
     static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
     private static final String TAG_APP = TAG + POSTFIX_APP;
@@ -251,33 +249,6 @@
         RESTARTING_PROCESS
     }
 
-    final ActivityTaskManagerService mAtmService;
-
-    /**
-     * When we are in the process of pausing an activity, before starting the
-     * next one, this variable holds the activity that is currently being paused.
-     */
-    ActivityRecord mPausingActivity = null;
-
-    /**
-     * This is the last activity that we put into the paused state.  This is
-     * used to determine if we need to do an activity transition while sleeping,
-     * when we normally hold the top activity paused.
-     */
-    ActivityRecord mLastPausedActivity = null;
-
-    /**
-     * Activities that specify No History must be removed once the user navigates away from them.
-     * If the device goes to sleep with such an activity in the paused state then we save it here
-     * and finish it later if another activity replaces it on wakeup.
-     */
-    ActivityRecord mLastNoHistoryActivity = null;
-
-    /**
-     * Current activity that is resumed, or null if there is none.
-     */
-    ActivityRecord mResumedActivity = null;
-
     // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
     // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
     // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
@@ -294,11 +265,6 @@
     boolean mConfigWillChange;
 
     /**
-     * When set, will force the stack to report as invisible.
-     */
-    boolean mForceHidden = false;
-
-    /**
      * Used to keep resumeTopActivityUncheckedLocked() from being entered recursively
      */
     boolean mInResumeTopActivity = false;
@@ -311,18 +277,12 @@
 
     int mCurrentUser;
 
-    /** The attached Display's unique identifier, or -1 if detached */
-    private int mDisplayId;
-    // Id of the previous display the stack was on.
-    int mPrevDisplayId = INVALID_DISPLAY;
-
     /** Unique identifier */
     final int mStackId;
 
     /** For comparison with DisplayContent bounds. */
     private Rect mTmpRect = new Rect();
     private Rect mTmpRect2 = new Rect();
-    private Rect mTmpRect3 = new Rect();
 
     /** For Pinned stack controlling. */
     private Rect mTmpToBounds = new Rect();
@@ -336,9 +296,6 @@
      */
     private final Rect mFullyAdjustedImeBounds = new Rect();
 
-    /** ActivityRecords that are exiting, but still on screen for animations. */
-    final ArrayList<ActivityRecord> mExitingActivities = new ArrayList<>();
-
     /** Detach this stack from its display when animation completes. */
     // TODO: maybe tie this to WindowContainer#removeChild some how...
     private boolean mDeferRemoval;
@@ -367,8 +324,6 @@
 
     Rect mPreAnimationBounds = new Rect();
 
-    private Dimmer mDimmer = new Dimmer(this);
-
     /**
      * For {@link #prepareSurfaces}.
      */
@@ -384,10 +339,6 @@
     /** List for processing through a set of activities */
     private final ArrayList<ActivityRecord> mTmpActivities = new ArrayList<>();
 
-    /** Run all ActivityStacks through this */
-    protected final ActivityStackSupervisor mStackSupervisor;
-    protected final RootWindowContainer mRootWindowContainer;
-
     private boolean mTopActivityOccludesKeyguard;
     private ActivityRecord mTopDismissingKeyguardActivity;
 
@@ -638,52 +589,68 @@
         }
     }
 
-    ActivityStack(DisplayContent display, int stackId, ActivityStackSupervisor supervisor,
-            int activityType) {
-        super(supervisor.mService.mWindowManager);
-        mStackId = stackId;
-        mDockedStackMinimizeThickness =
-                supervisor.mService.mWindowManager.mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.docked_stack_minimize_thickness);
-        EventLogTags.writeWmStackCreated(stackId);
-        mStackSupervisor = supervisor;
-        mAtmService = supervisor.mService;
-        mRootWindowContainer = mAtmService.mRootWindowContainer;
-        mHandler = new ActivityStackHandler(supervisor.mLooper);
-        mRemoteToken = new RemoteToken(this);
-        mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
-        // Set display id before setting activity and window type to make sure it won't affect
-        // stacks on a wrong display.
-        mDisplayId = display.mDisplayId;
+    ActivityStack(DisplayContent display, int id, ActivityStackSupervisor supervisor,
+            int activityType, ActivityInfo info, Intent intent) {
+        this(supervisor.mService, id, info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
+                null /*taskDescription*/, null /*stack*/);
+
         setActivityType(activityType);
     }
 
-    /**
-     * This should be called when an activity in a child task changes state. This should only
-     * be called from
-     * {@link Task#onActivityStateChanged(ActivityRecord, ActivityState, String)}.
-     * @param record The {@link ActivityRecord} whose state has changed.
-     * @param state The new state.
-     * @param reason The reason for the change.
-     */
-    void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
-        if (record == mResumedActivity && state != RESUMED) {
-            setResumedActivity(null, reason + " - onActivityStateChanged");
-        }
+    ActivityStack(ActivityTaskManagerService atmService, int id, ActivityInfo info, Intent _intent,
+            IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
+            ActivityManager.TaskDescription _taskDescription, ActivityStack stack) {
+        this(atmService, id, _intent,  null /*_affinityIntent*/, null /*_affinity*/,
+                null /*_rootAffinity*/, null /*_realActivity*/, null /*_origActivity*/,
+                false /*_rootWasReset*/, false /*_autoRemoveRecents*/, false /*_askedCompatMode*/,
+                UserHandle.getUserId(info.applicationInfo.uid), 0 /*_effectiveUid*/,
+                null /*_lastDescription*/, System.currentTimeMillis(),
+                true /*neverRelinquishIdentity*/,
+                _taskDescription != null ? _taskDescription : new ActivityManager.TaskDescription(),
+                id, INVALID_TASK_ID, INVALID_TASK_ID, 0 /*taskAffiliationColor*/,
+                info.applicationInfo.uid, info.packageName, info.resizeMode,
+                info.supportsPictureInPicture(), false /*_realActivitySuspended*/,
+                false /*userSetupComplete*/, INVALID_MIN_SIZE, INVALID_MIN_SIZE, info,
+                _voiceSession, _voiceInteractor, stack);
+    }
 
-        if (state == RESUMED) {
-            if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
-                    + reason);
-            setResumedActivity(record, reason + " - onActivityStateChanged");
-            if (record == mRootWindowContainer.getTopResumedActivity()) {
-                mAtmService.setResumedActivityUncheckLocked(record, reason);
-            }
-            mStackSupervisor.mRecentTasks.add(record.getTask());
-        }
+    ActivityStack(ActivityTaskManagerService atmService, int id, Intent _intent,
+            Intent _affinityIntent, String _affinity, String _rootAffinity,
+            ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
+            boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid,
+            String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity,
+            ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
+            int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid,
+            String callingPackage, int resizeMode, boolean supportsPictureInPicture,
+            boolean _realActivitySuspended, boolean userSetupComplete, int minWidth, int minHeight,
+            ActivityInfo info, IVoiceInteractionSession _voiceSession,
+            IVoiceInteractor _voiceInteractor, ActivityStack stack) {
+        super(atmService, id, _intent, _affinityIntent, _affinity, _rootAffinity,
+                _realActivity, _origActivity, _rootWasReset, _autoRemoveRecents, _askedCompatMode,
+                _userId, _effectiveUid, _lastDescription, lastTimeMoved, neverRelinquishIdentity,
+                _lastTaskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
+                callingUid, callingPackage, resizeMode, supportsPictureInPicture,
+                _realActivitySuspended, userSetupComplete, minWidth, minHeight, info, _voiceSession,
+                _voiceInteractor, stack);
+
+        mStackId = mTaskId;
+        mDockedStackMinimizeThickness = mWmService.mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_minimize_thickness);
+        EventLogTags.writeWmStackCreated(id);
+        mHandler = new ActivityStackHandler(mStackSupervisor.mLooper);
+        mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
     }
 
     @Override
     public void onConfigurationChanged(Configuration newParentConfig) {
+        // Calling Task#onConfigurationChanged() for leaf task since the ops in this method are
+        // particularly for ActivityStack, like preventing bounds changes when inheriting certain
+        // windowing mode.
+        if (!isRootTask()) {
+            super.onConfigurationChanged(newParentConfig);
+            return;
+        }
+
         final int prevWindowingMode = getWindowingMode();
         final boolean prevIsAlwaysOnTop = isAlwaysOnTop();
         final int prevRotation = getWindowConfiguration().getRotation();
@@ -801,10 +768,16 @@
 
     @Override
     public void setWindowingMode(int windowingMode) {
+        // Calling Task#setWindowingMode() for leaf task since this is the a specialization of
+        // {@link #setWindowingMode(int)} for ActivityStack.
+        if (!isRootTask()) {
+            super.setWindowingMode(windowingMode);
+            return;
+        }
+
         setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
                 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
                 false /* creating */);
-
         windowingMode = getWindowingMode();
         /*
          * Different windowing modes may be managed by different task organizers. If
@@ -893,7 +866,8 @@
                 // Looks like we can't launch in split screen mode or the stack we are launching
                 // doesn't support split-screen mode, go ahead an dismiss split-screen and display a
                 // warning toast about it.
-                mAtmService.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
+                mAtmService.getTaskChangeNotificationController()
+                        .notifyActivityDismissingDockedStack();
                 final ActivityStack primarySplitStack = display.getSplitScreenPrimaryStack();
                 primarySplitStack.setWindowingModeInSurfaceTransaction(WINDOWING_MODE_UNDEFINED,
                         false /* animate */, false /* showRecents */,
@@ -972,7 +946,7 @@
                         false /* preserveWindows */, true /* deferResume */);
             }
         } finally {
-            if (showRecents && !alreadyInSplitScreenMode && mDisplayId == DEFAULT_DISPLAY
+            if (showRecents && !alreadyInSplitScreenMode && isOnHomeDisplay()
                     && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                 // Make sure recents stack exist when creating a dock stack as it normally needs to
                 // be on the other side of the docked stack and we make visibility decisions based
@@ -1029,10 +1003,6 @@
         return getDisplayContent();
     }
 
-    int getDisplayId() {
-        return mDisplayId;
-    }
-
     /**
      * Defers updating the bounds of the stack. If the stack was resized/repositioned while
      * deferring, the bounds will update in {@link #continueUpdateBounds()}.
@@ -1138,10 +1108,6 @@
         return r.getTask().mTaskId != taskId && r.appToken != notTop && r.canBeTopRunning();
     }
 
-    ActivityRecord getTopNonFinishingActivity() {
-        return getTopActivity(false /*includeFinishing*/, true /*includeOverlays*/);
-    }
-
     ActivityRecord isInStackLocked(IBinder token) {
         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
         return isInStackLocked(r);
@@ -1172,11 +1138,7 @@
     }
 
     final boolean isOnHomeDisplay() {
-        return mDisplayId == DEFAULT_DISPLAY;
-    }
-
-    private boolean returnsToHomeStack() {
-        return !inMultiWindowMode() && hasChild() && getBottomMostTask().returnsToHomeStack();
+        return getDisplayId() == DEFAULT_DISPLAY;
     }
 
     void moveToFront(String reason) {
@@ -1280,11 +1242,11 @@
 
         super.switchUser(userId);
         forAllTasks((t) -> {
-            if (t.mWmService.isCurrentProfile(t.mUserId) || t.showForAllUsers()) {
+            if (t.showToCurrentUser()) {
                 mChildren.remove(t);
                 mChildren.add(t);
             }
-        });
+        }, true /* traverseTopToBottom */, this);
     }
 
     void minimalResumeActivityLocked(ActivityRecord r) {
@@ -1609,45 +1571,6 @@
         mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
     }
 
-    /**
-     * Returns true if the stack is translucent and can have other contents visible behind it if
-     * needed. A stack is considered translucent if it don't contain a visible or
-     * starting (about to be visible) activity that is fullscreen (opaque).
-     * @param starting The currently starting activity or null if there is none.
-     */
-    @VisibleForTesting
-    boolean isStackTranslucent(ActivityRecord starting) {
-        if (!isAttached() || mForceHidden) {
-            return true;
-        }
-        final PooledPredicate p = PooledLambda.obtainPredicate(ActivityStack::isOpaqueActivity,
-                PooledLambda.__(ActivityRecord.class), starting);
-        final ActivityRecord opaque = getActivity(p);
-        p.recycle();
-        return opaque == null;
-    }
-
-    private static boolean isOpaqueActivity(ActivityRecord r, ActivityRecord starting) {
-        if (r.finishing) {
-            // We don't factor in finishing activities when determining translucency since
-            // they will be gone soon.
-            return false;
-        }
-
-        if (!r.visibleIgnoringKeyguard && r != starting) {
-            // Also ignore invisible activities that are not the currently starting
-            // activity (about to be visible).
-            return false;
-        }
-
-        if (r.occludesParent() || r.hasWallpaper) {
-            // Stack isn't translucent if it has at least one fullscreen activity
-            // that is visible.
-            return true;
-        }
-        return false;
-    }
-
     boolean isTopStackOnDisplay() {
         final DisplayContent display = getDisplay();
         return display != null && display.isTopStack(this);
@@ -1667,15 +1590,6 @@
         return topActivity != null && topActivity.mVisibleRequested;
     }
 
-    /**
-     * Indicate whether the first task in this stack is controlled by a TaskOrganizer. We aren't
-     * expecting to use the TaskOrganizer in multiple task per stack scenarios so checking
-     * the first one is ok.
-     */
-    boolean isControlledByTaskOrganizer() {
-        return getChildCount() > 0 && getTopMostTask().mTaskOrganizer != null;
-    }
-
     private static void transferSingleTaskToOrganizer(Task tr, ITaskOrganizer organizer) {
         tr.setTaskOrganizer(organizer);
     }
@@ -1690,7 +1604,7 @@
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 ActivityStack::transferSingleTaskToOrganizer,
                 PooledLambda.__(Task.class), organizer);
-        forAllTasks(c);
+        forAllTasks(c, true /* traverseTopToBottom */, this);
         c.recycle();
     }
 
@@ -1699,6 +1613,7 @@
      *
      * @param starting The currently starting activity or null if there is none.
      */
+    @Override
     boolean shouldBeVisible(ActivityRecord starting) {
         return getVisibility(starting) != STACK_VISIBILITY_INVISIBLE;
     }
@@ -1756,7 +1671,7 @@
                         break;
                     }
                 }
-                if (other.isStackTranslucent(starting)) {
+                if (other.isTranslucent(starting)) {
                     // Can be visible behind a translucent fullscreen stack.
                     gotTranslucentFullscreen = true;
                     continue;
@@ -1765,7 +1680,7 @@
             } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                     && !gotOpaqueSplitScreenPrimary) {
                 gotSplitScreenStack = true;
-                gotTranslucentSplitScreenPrimary = other.isStackTranslucent(starting);
+                gotTranslucentSplitScreenPrimary = other.isTranslucent(starting);
                 gotOpaqueSplitScreenPrimary = !gotTranslucentSplitScreenPrimary;
                 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                         && gotOpaqueSplitScreenPrimary) {
@@ -1775,7 +1690,7 @@
             } else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
                     && !gotOpaqueSplitScreenSecondary) {
                 gotSplitScreenStack = true;
-                gotTranslucentSplitScreenSecondary = other.isStackTranslucent(starting);
+                gotTranslucentSplitScreenSecondary = other.isTranslucent(starting);
                 gotOpaqueSplitScreenSecondary = !gotTranslucentSplitScreenSecondary;
                 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
                         && gotOpaqueSplitScreenSecondary) {
@@ -1876,13 +1791,7 @@
         return inPinnedWindowingMode();
     }
 
-    @Override
-    public boolean supportsSplitScreenWindowingMode() {
-        final Task topTask = getTopMostTask();
-        return super.supportsSplitScreenWindowingMode()
-                && (topTask == null || topTask.supportsSplitScreenWindowingMode());
-    }
-
+    // TODO(NOW!)
     /**
      * Returns {@code true} if this is the top-most split-screen-primary or
      * split-screen-secondary stack, {@code false} otherwise.
@@ -1918,7 +1827,9 @@
      * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
      */
     boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) {
-        final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
+        int displayId = getDisplayId();
+        if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
+
         final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController()
                 .isKeyguardOrAodShowing(displayId);
         final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
@@ -2084,24 +1995,6 @@
         return result;
     }
 
-    /**
-     * Returns the currently resumed activity.
-     */
-    protected ActivityRecord getResumedActivity() {
-        return mResumedActivity;
-    }
-
-    private void setResumedActivity(ActivityRecord r, String reason) {
-        if (mResumedActivity == r) {
-            return;
-        }
-
-        if (DEBUG_STACK) Slog.d(TAG_STACK, "setResumedActivity stack:" + this + " + from: "
-                + mResumedActivity + " to:" + r + " reason:" + reason);
-        mResumedActivity = r;
-        mStackSupervisor.updateTopResumedActivityIfNeeded();
-    }
-
     @GuardedBy("mService")
     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
         if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
@@ -2412,7 +2305,7 @@
                 // result of invisible window resize.
                 // TODO: Remove this once visibilities are set correctly immediately when
                 // starting an activity.
-                notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, mDisplayId,
+                notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(),
                         true /* markFrozenIfConfigChanged */, false /* deferResume */);
             }
 
@@ -2553,7 +2446,7 @@
         ActivityOptions.abort(options);
         if (DEBUG_STATES) Slog.d(TAG_STATES,
                 "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
-        return mRootWindowContainer.resumeHomeActivity(prev, reason, mDisplayId);
+        return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayId());
     }
 
     void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
@@ -2827,7 +2720,7 @@
     void finishVoiceTask(IVoiceInteractionSession session) {
         final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::finishIfVoiceTask,
                 PooledLambda.__(Task.class), session.asBinder());
-        forAllTasks(c);
+        forAllTasks(c, true /* traverseTopToBottom */, this);
         c.recycle();
     }
 
@@ -3020,29 +2913,6 @@
         return foundParentInTask;
     }
 
-    /**
-     * Remove any state associated with the {@link ActivityRecord}. This should be called whenever
-     * an activity moves away from the stack.
-     */
-    void onActivityRemovedFromStack(ActivityRecord r) {
-        r.removeTimeouts();
-
-        mExitingActivities.remove(r);
-
-        if (mResumedActivity != null && mResumedActivity == r) {
-            setResumedActivity(null, "onActivityRemovedFromStack");
-        }
-        if (mPausingActivity != null && mPausingActivity == r) {
-            mPausingActivity = null;
-        }
-    }
-
-    void onActivityAddedToStack(ActivityRecord r) {
-        if (r.isState(RESUMED)) {
-            setResumedActivity(r, "onActivityAddedToStack");
-        }
-    }
-
     void removeLaunchTickMessages() {
         forAllActivities(ActivityRecord::removeLaunchTickRunnable);
     }
@@ -3141,7 +3011,8 @@
                 mRootWindowContainer.resumeFocusedStacksTopActivities();
             }
             EventLogTags.writeWmTaskToFront(tr.mUserId, tr.mTaskId);
-            mAtmService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.getTaskInfo());
+            mAtmService.getTaskChangeNotificationController()
+                    .notifyTaskMovedToFront(tr.getTaskInfo());
         } finally {
             getDisplay().continueUpdateImeTarget();
         }
@@ -3239,7 +3110,7 @@
             final PooledConsumer c = PooledLambda.obtainConsumer(
                     ActivityStack::processTaskResizeBounds, PooledLambda.__(Task.class),
                     taskBounds, tempTaskInsetBounds);
-            forAllTasks(c);
+            forAllTasks(c, true /* traverseTopToBottom */, this);
             c.recycle();
 
             setBounds(bounds);
@@ -3276,7 +3147,7 @@
 
         final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskBounds,
                 PooledLambda.__(Task.class), bounds);
-        forAllTasks(c);
+        forAllTasks(c, true /* traverseTopToBottom */, this);
         c.recycle();
     }
 
@@ -3292,7 +3163,7 @@
 
         final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskDisplayedBounds,
                 PooledLambda.__(Task.class), bounds);
-        forAllTasks(c);
+        forAllTasks(c, true /* traverseTopToBottom */, this);
         c.recycle();
     }
 
@@ -3384,7 +3255,6 @@
 
     private boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
             boolean dumpClient, String dumpPackage, boolean needSep) {
-
         if (!hasChild()) {
             return false;
         }
@@ -3403,11 +3273,11 @@
             final ArrayList<ActivityRecord> activities = new ArrayList<>();
             // Add activities by traversing the hierarchy from bottom to top, since activities
             // are dumped in reverse order in {@link ActivityStackSupervisor#dumpHistoryList()}.
-            forAllActivities((Consumer<ActivityRecord>) activities::add,
+            task.forAllActivities((Consumer<ActivityRecord>) activities::add,
                     false /* traverseTopToBottom */);
             dumpHistoryList(fd, pw, activities, prefix, "Hist", true, !dumpAll, dumpClient,
                     dumpPackage, false, null, task);
-        });
+        }, true /* traverseTopToBottom */, this);
         return true;
     }
 
@@ -3458,49 +3328,9 @@
         }
     }
 
-    /**
-     * Removes the input task from this stack.
-     *
-     * @param child to remove.
-     * @param reason for removal.
-     */
-    void removeChild(WindowContainer child, String reason) {
-        if (!mChildren.contains(child)) {
-            // Not really in this stack anymore...
-            return;
-        }
-
-        final DisplayContent display = getDisplay();
-        if (DEBUG_TASK_MOVEMENT) {
-            Slog.d(TAG_WM, "removeChild: task=" + child + " reason=" + reason);
-        }
-
-        super.removeChild(child);
-
-        EventLogTags.writeWmRemoveTask(((Task) child).mTaskId, mStackId);
-
-        if (display.isSingleTaskInstance()) {
-            mAtmService.notifySingleTaskDisplayEmpty(display.mDisplayId);
-        }
-
-        display.mDisplayContent.setLayoutNeeded();
-
-        if (!hasChild()) {
-            // Stack is now empty...
-          removeIfPossible();
-        }
-    }
-
-    @Override
-    void removeChild(WindowContainer child) {
-        removeChild(child, "removeChild");
-    }
-
-    Task createTask(int taskId, ActivityInfo info, Intent intent,
-            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
-            boolean toTop) {
-        return createTask(taskId, info, intent, voiceSession, voiceInteractor, toTop,
-                null /*activity*/, null /*source*/, null /*options*/);
+    Task createTask(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
+        return createTask(taskId, info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
+                toTop, null /*activity*/, null /*source*/, null /*options*/);
     }
 
     Task createTask(int taskId, ActivityInfo info, Intent intent,
@@ -3511,7 +3341,8 @@
                 mAtmService, taskId, info, intent, voiceSession, voiceInteractor, this);
         // add the task to stack first, mTaskPositioner might need the stack association
         addChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
-        final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
+        int displayId = getDisplayId();
+        if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
         final boolean isLockscreenShown = mAtmService.mStackSupervisor.getKeyguardController()
                 .isKeyguardOrAodShowing(displayId);
         if (!mStackSupervisor.getLaunchParamsController()
@@ -3522,14 +3353,25 @@
         return task;
     }
 
-    void addChild(final Task task, final boolean toTop, boolean showForAllUsers) {
+    void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) {
         if (isSingleTaskInstance() && hasChild()) {
             throw new IllegalStateException("Can only have one child on stack=" + this);
         }
 
-        // We only want to move the parents to the parents if we are creating this task at the
-        // top of its stack.
-        addChild(task, toTop ? MAX_VALUE : 0, showForAllUsers, toTop /*moveParents*/);
+        Task task = child.asTask();
+        try {
+
+            if (task != null) {
+                task.setForceShowForAllUsers(showForAllUsers);
+            }
+            // We only want to move the parents to the parents if we are creating this task at the
+            // top of its stack.
+            addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/);
+        } finally {
+            if (task != null) {
+                task.setForceShowForAllUsers(false);
+            }
+        }
     }
 
     void positionChildAt(Task task, int position) {
@@ -3747,16 +3589,12 @@
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 ActivityStackSupervisor::updatePictureInPictureMode, mStackSupervisor,
                 PooledLambda.__(Task.class), targetStackBounds, forceUpdate);
-        forAllTasks(c);
+        forAllTasks(c, true /* traverseTopToBottom */, this);
         c.recycle();
     }
 
-    public int getStackId() {
-        return mStackId;
-    }
-
     void prepareFreezingTaskBounds() {
-        forAllTasks(Task::prepareFreezingBounds);
+        forAllTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */, this);
     }
 
     /**
@@ -3788,7 +3626,7 @@
             final PooledConsumer c = PooledLambda.obtainConsumer(Task::alignToAdjustedBounds,
                     PooledLambda.__(Task.class), adjusted ? mAdjustedBounds : getRawBounds(),
                     insetBounds, alignBottom);
-            forAllTasks(c);
+            forAllTasks(c, true /* traverseTopToBottom */, this);
             c.recycle();
         }
 
@@ -3798,7 +3636,13 @@
 
     @Override
     public int setBounds(Rect bounds) {
-        return setBounds(getRequestedOverrideBounds(), bounds);
+        // Calling Task#setBounds() for leaf task since this is the a specialization of
+        // {@link #setBounds(int)} for ActivityStack.
+        if (!isRootTask()) {
+            return super.setBounds(bounds);
+        } else {
+            return setBounds(getRequestedOverrideBounds(), bounds);
+        }
     }
 
     private int setBounds(Rect existing, Rect bounds) {
@@ -4038,30 +3882,15 @@
      * Put a Task in this stack. Used for adding only.
      * When task is added to top of the stack, the entire branch of the hierarchy (including stack
      * and display) will be brought to top.
-     * @param task The task to add.
+     * @param child The child to add.
      * @param position Target position to add the task to.
-     * @param showForAllUsers Whether to show the task regardless of the current user.
      */
-    private void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
-        try {
-            // Force show for all user so task can be position correctly based on which user is
-            // active. We clear the force show below.
-            task.setForceShowForAllUsers(showForAllUsers);
-            // Add child task.
-            addChild(task, null);
+    private void addChild(WindowContainer child, int position, boolean moveParents) {
+        // Add child task.
+        addChild(child, null);
 
-            // Move child to a proper position, as some restriction for position might apply.
-            positionChildAt(position, task, moveParents /* includingParents */);
-
-        } finally {
-            task.setForceShowForAllUsers(false);
-        }
-    }
-
-    @Override
-    void addChild(WindowContainer child, int position) {
-        final Task task = (Task) child;
-        addChild(task, position, task.showForAllUsers(), false /* includingParents */);
+        // Move child to a proper position, as some restriction for position might apply.
+        positionChildAt(position, child, moveParents /* includingParents */);
     }
 
     void positionChildAtTop(Task child) {
@@ -4099,29 +3928,18 @@
     }
 
     @Override
-    void positionChildAt(int position, WindowContainer child, boolean includingParents) {
-        final Task task = (Task) child;
-        final int targetPosition = findPositionForTask(task, position);
-        super.positionChildAt(targetPosition, child, includingParents);
-
-        // Log positioning.
-        if (DEBUG_TASK_MOVEMENT) {
-            Slog.d(TAG_WM, "positionTask: task=" + this + " position=" + position);
-        }
-
-        final int toTop = targetPosition == mChildren.size() - 1 ? 1 : 0;
-        EventLogTags.writeWmTaskMoved(task.mTaskId, toTop, targetPosition);
-    }
-
-    @Override
     void onChildPositionChanged(WindowContainer child) {
         if (!mChildren.contains(child)) {
             return;
         }
 
-        final Task task = (Task) child;
-        final boolean isTop = getTopChild() == task;
-        task.updateTaskMovement(isTop);
+        final boolean isTop = getTopChild() == child;
+
+        final Task task = child.asTask();
+        if (task != null) {
+            task.updateTaskMovement(isTop);
+        }
+
         if (isTop) {
             final DisplayContent displayContent = getDisplayContent();
             displayContent.layoutAndAssignWindowLayersIfNeeded();
@@ -4129,34 +3947,17 @@
     }
 
     @Override
-    protected void onParentChanged(
-            ConfigurationContainer newParent, ConfigurationContainer oldParent) {
+    void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
         final DisplayContent display = newParent != null
                 ? ((WindowContainer) newParent).getDisplayContent() : null;
         final DisplayContent oldDisplay = oldParent != null
                 ? ((WindowContainer) oldParent).getDisplayContent() : null;
 
-        mDisplayId = (display != null) ? display.mDisplayId : INVALID_DISPLAY;
-        mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY;
-
-        if (display != null) {
-            // Rotations are relative to the display. This means if there are 2 displays rotated
-            // differently (eg. 2 monitors with one landscape and one portrait), moving a stack
-            // from one to the other could look like a rotation change. To prevent this
-            // apparent rotation change (and corresponding bounds rotation), pretend like our
-            // current rotation is already the same as the new display.
-            // Note, if ActivityStack or related logic ever gets nested, this logic will need
-            // to move to onConfigurationChanged.
-            getConfiguration().windowConfiguration.setRotation(
-                    display.getWindowConfiguration().getRotation());
-        }
         super.onParentChanged(newParent, oldParent);
-        if (getParent() == null && mDisplayContent != null) {
-            EventLogTags.writeWmStackRemoved(mStackId);
-            mDisplayContent = null;
-            mWmService.mWindowPlacerLocked.requestTraversal();
-        }
-        if (display != null && inSplitScreenPrimaryWindowingMode()) {
+
+        if (display != null && inSplitScreenPrimaryWindowingMode()
+                // only do this for the base stack
+                && !newParent.inSplitScreenPrimaryWindowingMode()) {
             // If we created a docked stack we want to resize it so it resizes all other stacks
             // in the system.
             getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
@@ -4164,7 +3965,6 @@
             mStackSupervisor.resizeDockedStackLocked(getRequestedOverrideBounds(), mTmpRect,
                     mTmpRect2, null, null, PRESERVE_WINDOWS);
         }
-        mRootWindowContainer.updateUIDsPresentOnDisplay();
 
         // Resume next focusable stack after reparenting to another display if we aren't removing
         // the prevous display.
@@ -4178,68 +3978,6 @@
         newParent.moveStackToDisplay(this, onTop);
     }
 
-    // TODO: We should really have users as a window container in the hierarchy so that we don't
-    // have to do complicated things like we are doing in this method.
-    int findPositionForTask(Task task, int targetPosition) {
-        final boolean canShowTask = task.showToCurrentUser();
-
-        final int stackSize = mChildren.size();
-        int minPosition = 0;
-        int maxPosition = stackSize - 1;
-
-        if (canShowTask) {
-            minPosition = computeMinPosition(minPosition, stackSize);
-        } else {
-            maxPosition = computeMaxPosition(maxPosition);
-        }
-
-        // preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.
-        if (targetPosition == POSITION_BOTTOM && minPosition == 0) {
-            return POSITION_BOTTOM;
-        } else if (targetPosition == POSITION_TOP && maxPosition == (stackSize - 1)) {
-            return POSITION_TOP;
-        }
-        // Reset position based on minimum/maximum possible positions.
-        return Math.min(Math.max(targetPosition, minPosition), maxPosition);
-    }
-
-    /** Calculate the minimum possible position for a task that can be shown to the user.
-     *  The minimum position will be above all other tasks that can't be shown.
-     *  @param minPosition The minimum position the caller is suggesting.
-     *                  We will start adjusting up from here.
-     *  @param size The size of the current task list.
-     */
-    // TODO(task-hierarchy): Move user to their own window container.
-    private int computeMinPosition(int minPosition, int size) {
-        while (minPosition < size) {
-            final Task tmpTask = (Task) mChildren.get(minPosition);
-            final boolean canShowTmpTask = tmpTask.showToCurrentUser();
-            if (canShowTmpTask) {
-                break;
-            }
-            minPosition++;
-        }
-        return minPosition;
-    }
-
-    /** Calculate the maximum possible position for a task that can't be shown to the user.
-     *  The maximum position will be below all other tasks that can be shown.
-     *  @param maxPosition The maximum position the caller is suggesting.
-     *                  We will start adjusting down from here.
-     */
-    // TODO(task-hierarchy): Move user to their own window container.
-    private int computeMaxPosition(int maxPosition) {
-        while (maxPosition > 0) {
-            final Task tmpTask = (Task) mChildren.get(maxPosition);
-            final boolean canShowTmpTask = tmpTask.showToCurrentUser();
-            if (!canShowTmpTask) {
-                break;
-            }
-            maxPosition--;
-        }
-        return maxPosition;
-    }
-
     private void updateSurfaceBounds() {
         updateSurfaceSize(getPendingTransaction());
         updateSurfacePosition();
@@ -4456,15 +4194,6 @@
                 false /* deferResume */);
     }
 
-    @Override
-    void removeIfPossible() {
-        if (isAnimating(TRANSITION | CHILDREN)) {
-            mDeferRemoval = true;
-            return;
-        }
-        removeImmediately();
-    }
-
     /**
      * Adjusts the stack bounds if the IME is visible.
      *
@@ -4568,12 +4297,14 @@
                 t.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
                 t.setWaitingForDrawnIfResizingChanged();
             }
-        });
+        }, true /* traverseTopToBottom */, this);
     }
 
     /** Resets the resizing state of all windows. */
     void endImeAdjustAnimation() {
-        forAllTasks((t) -> { t.setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER); });
+        forAllTasks((t) -> {
+            t.setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
+        }, true /* traverseTopToBottom */, this);
     }
 
     private int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
@@ -4751,14 +4482,6 @@
         return mMinimizeAmount != 0f;
     }
 
-    /**
-     * @return {@code true} if we have a {@link Task} that is animating (currently only used for the
-     *         recents animation); {@code false} otherwise.
-     */
-    boolean isTaskAnimating() {
-        return getTask(Task::isTaskAnimating) != null;
-    }
-
     @Override
     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
         pw.println(prefix + "mStackId=" + mStackId);
@@ -4792,11 +4515,6 @@
         mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix);
     }
 
-    @Override
-    boolean fillsParent() {
-        return matchParentBounds();
-    }
-
     String getName() {
         return toShortString();
     }
@@ -4946,18 +4664,6 @@
         }
     }
 
-    @Override
-    protected void onAnimationFinished() {
-        super.onAnimationFinished();
-        // TODO(b/142617871): we may need to add animation type parameter on onAnimationFinished to
-        //  identify if the callback is for launch animation finish and then calling
-        //  activity#onAnimationFinished.
-        final ActivityRecord activity = getTopMostActivity();
-        if (activity != null) {
-            activity.onAnimationFinished();
-        }
-    }
-
     /**
      * Sets the current picture-in-picture aspect ratio.
      */
@@ -5008,7 +4714,7 @@
     /** Called immediately prior to resizing the tasks at the end of the pinned stack animation. */
     void onPipAnimationEndResize() {
         mBoundsAnimating = false;
-        forAllTasks(Task::clearPreserveNonFloatingState, false);
+        forAllTasks(Task::clearPreserveNonFloatingState, false /* traverseTopToBottom */, this);
         mWmService.requestTraversal();
     }
 
@@ -5108,24 +4814,6 @@
     }
 
     @Override
-    Dimmer getDimmer() {
-        return mDimmer;
-    }
-
-    @Override
-    void prepareSurfaces() {
-        mDimmer.resetDimStates();
-        super.prepareSurfaces();
-        getDimBounds(mTmpDimBoundsRect);
-
-        // Bounds need to be relative, as the dim layer is a child.
-        mTmpDimBoundsRect.offsetTo(0, 0);
-        if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
-            scheduleAnimation();
-        }
-    }
-
-    @Override
     public boolean setPinnedStackAlpha(float alpha) {
         // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mWmService.mGlobalLock) {
@@ -5144,49 +4832,10 @@
         return mDisplayContent.getDisplayInfo();
     }
 
-    void dim(float alpha) {
-        mDimmer.dimAbove(getPendingTransaction(), alpha);
-        scheduleAnimation();
-    }
-
-    void stopDimming() {
-        mDimmer.stopDim(getPendingTransaction());
-        scheduleAnimation();
-    }
-
     AnimatingActivityRegistry getAnimatingActivityRegistry() {
         return mAnimatingActivityRegistry;
     }
 
-    @Override
-    void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
-            Rect outSurfaceInsets) {
-        final Task task = getTopMostTask();
-        if (task != null) {
-            task.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
-        } else {
-            super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
-        }
-    }
-
-    @Override
-    RemoteAnimationTarget createRemoteAnimationTarget(
-            RemoteAnimationController.RemoteAnimationRecord record) {
-        final Task task = getTopMostTask();
-        return task != null ? task.createRemoteAnimationTarget(record) : null;
-    }
-
-    @Override
-    public String toString() {
-        return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
-                + " stackId=" + mStackId + " type=" + activityTypeToString(getActivityType())
-                + " mode=" + windowingModeToString(getWindowingMode())
-                + " visible=" + shouldBeVisible(null /* starting */)
-                + " translucent=" + isStackTranslucent(null /* starting */)
-                + ", "
-                + getChildCount() + " tasks}";
-    }
-
     void executeAppTransition(ActivityOptions options) {
         getDisplay().mDisplayContent.executeAppTransition();
         ActivityOptions.abort(options);
@@ -5209,6 +4858,7 @@
         return shouldSleepActivities() || mAtmService.mShuttingDown;
     }
 
+    @Override
     public void dumpDebug(ProtoOutputStream proto, long fieldId,
             @WindowTraceLogLevel int logLevel) {
         final long token = proto.start(fieldId);
@@ -5216,12 +4866,12 @@
         proto.write(com.android.server.am.ActivityStackProto.ID, mStackId);
 
         forAllTasks((t) -> {
-            t.dumpDebug(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
-        });
+            t.dumpDebugInner(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
+        }, true /* traverseTopToBottom */, this);
         if (mResumedActivity != null) {
             mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
         }
-        proto.write(DISPLAY_ID, mDisplayId);
+        proto.write(DISPLAY_ID, getDisplayId());
         if (!matchParentBounds()) {
             final Rect bounds = getRequestedOverrideBounds();
             bounds.dumpDebug(proto, com.android.server.am.ActivityStackProto.BOUNDS);
@@ -5242,7 +4892,9 @@
         final long token = proto.start(fieldId);
         super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
         proto.write(StackProto.ID, mStackId);
-        forAllTasks((t) -> { t.dumpDebugInnerTaskOnly(proto, StackProto.TASKS, logLevel); });
+        forAllTasks((t) -> {
+            t.dumpDebugInnerTaskOnly(proto, StackProto.TASKS, logLevel);
+        }, true /* traverseTopToBottom */, this);
         proto.write(FILLS_PARENT, matchParentBounds());
         getRawBounds().dumpDebug(proto, StackProto.BOUNDS);
         proto.write(DEFER_REMOVAL, mDeferRemoval);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 0a68408..f2ce7e8 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -419,7 +419,7 @@
 
             final PooledConsumer c = PooledLambda.obtainConsumer(
                     MoveTaskToFullscreenHelper::processTask, this, PooledLambda.__(Task.class));
-            fromStack.forAllTasks(c, false);
+            fromStack.forAllTasks(c, false /* traverseTopToBottom */, fromStack);
             c.recycle();
             mToDisplay = null;
             mTopTask = null;
@@ -946,7 +946,7 @@
                     // This is the second time we failed -- finish activity and give up.
                     Slog.e(TAG, "Second failure launching "
                             + r.intent.getComponent().flattenToShortString() + ", giving up", e);
-                    proc.appDied();
+                    proc.appDied("2nd-crash");
                     r.finishIfPossible("2nd-crash", false /* oomAdj */);
                     return false;
                 }
@@ -1724,7 +1724,7 @@
         } else {
             final PooledConsumer c = PooledLambda.obtainConsumer(
                     ActivityStackSupervisor::processRemoveTask, this, PooledLambda.__(Task.class));
-            stack.forAllTasks(c);
+            stack.forAllTasks(c, true /* traverseTopToBottom */, stack);
             c.recycle();
         }
     }
@@ -1849,14 +1849,14 @@
     boolean restoreRecentTaskLocked(Task task, ActivityOptions aOptions, boolean onTop) {
         final ActivityStack stack =
                 mRootWindowContainer.getLaunchStack(null, aOptions, task, onTop);
-        final ActivityStack currentStack = task.getStack();
+        final WindowContainer parent = task.getParent();
 
-        if (currentStack == stack) {
+        if (parent == stack) {
             // Nothing else to do since it is already restored in the right stack.
             return true;
         }
 
-        if (currentStack != null) {
+        if (parent != null) {
             // Task has already been restored once. Just re-parent it to the new stack.
             task.reparent(stack, POSITION_TOP, true /*moveParents*/, "restoreRecentTaskLocked");
             return true;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 47e8b87..8491bc2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -306,7 +306,7 @@
  */
 public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
-    private static final String TAG_STACK = TAG + POSTFIX_STACK;
+    static final String TAG_STACK = TAG + POSTFIX_STACK;
     static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
@@ -2057,8 +2057,9 @@
     public int getDisplayId(IBinder activityToken) throws RemoteException {
         synchronized (mGlobalLock) {
             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
-            if (stack != null && stack.getDisplayId() != INVALID_DISPLAY) {
-                return stack.getDisplayId();
+            if (stack != null) {
+                final int displayId = stack.getDisplayId();
+                return displayId != INVALID_DISPLAY ? displayId : DEFAULT_DISPLAY;
             }
             return DEFAULT_DISPLAY;
         }
@@ -3216,8 +3217,7 @@
 
                 final ActivityStack stack = r.getActivityStack();
                 final Task task = stack.createTask(
-                        mStackSupervisor.getNextTaskIdForUser(r.mUserId), ainfo, intent,
-                        null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
+                        mStackSupervisor.getNextTaskIdForUser(r.mUserId), ainfo, intent, !ON_TOP);
                 if (!mRecentTasks.addToBottom(task)) {
                     // The app has too many tasks already and we can't add any more
                     stack.removeChild(task, "addAppTask");
@@ -4385,7 +4385,7 @@
 
         if (params.hasSetAspectRatio()
                 && !mWindowManager.isValidPictureInPictureAspectRatio(
-                        r.getDisplayId(), params.getAspectRatio())) {
+                        r.getDisplay(), params.getAspectRatio())) {
             final float minAspectRatio = mContext.getResources().getFloat(
                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
             final float maxAspectRatio = mContext.getResources().getFloat(
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 369dde6..3927d5f 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -352,6 +352,7 @@
      * Apply animation to the set of window containers.
      *
      * @param wcs The list of {@link WindowContainer}s to which an app transition animation applies.
+     * @param apps The list of {@link ActivityRecord}s being transitioning.
      * @param transit The current transition type.
      * @param visible {@code true} if the apps becomes visible, {@code false} if the apps becomes
      *                invisible.
@@ -359,12 +360,28 @@
      * @param voiceInteraction {@code true} if one of the apps in this transition belongs to a voice
      *                         interaction session driving task.
      */
-    private void applyAnimations(ArraySet<WindowContainer> wcs, @TransitionType int transit,
-            boolean visible, LayoutParams animLp, boolean voiceInteraction) {
-        final int appsCount = wcs.size();
-        for (int i = 0; i < appsCount; i++) {
+    private void applyAnimations(ArraySet<WindowContainer> wcs, ArraySet<ActivityRecord> apps,
+            @TransitionType int transit, boolean visible, LayoutParams animLp,
+            boolean voiceInteraction) {
+        final int wcsCount = wcs.size();
+        for (int i = 0; i < wcsCount; i++) {
             final WindowContainer wc = wcs.valueAt(i);
-            wc.applyAnimation(animLp, transit, visible, voiceInteraction);
+            // If app transition animation target is promoted to higher level, SurfaceAnimator
+            // triggers WC#onAnimationFinished only on the promoted target. So we need to take care
+            // of triggering AR#onAnimationFinished on each ActivityRecord which is a part of the
+            // app transition.
+            final ArrayList<ActivityRecord> transitioningDecendants = new ArrayList<>();
+            for (int j = 0; j < apps.size(); ++j) {
+                final ActivityRecord app = apps.valueAt(j);
+                if (app.isDescendantOf(wc)) {
+                    transitioningDecendants.add(app);
+                }
+            }
+            wc.applyAnimation(animLp, transit, visible, voiceInteraction, () -> {
+                for (int j = 0; j < transitioningDecendants.size(); ++j) {
+                    transitioningDecendants.get(j).onAnimationFinished();
+                }
+            });
         }
     }
 
@@ -495,8 +512,10 @@
                 openingApps, closingApps, true /* visible */);
         final ArraySet<WindowContainer> closingWcs = getAnimationTargets(
                 openingApps, closingApps, false /* visible */);
-        applyAnimations(openingWcs, transit, true /* visible */, animLp, voiceInteraction);
-        applyAnimations(closingWcs, transit, false /* visible */, animLp, voiceInteraction);
+        applyAnimations(openingWcs, openingApps, transit, true /* visible */, animLp,
+                voiceInteraction);
+        applyAnimations(closingWcs, closingApps, transit, false /* visible */, animLp,
+                voiceInteraction);
 
         final AccessibilityController accessibilityController =
                 mDisplayContent.mWmService.mAccessibilityController;
@@ -575,7 +594,8 @@
             ActivityRecord activity = apps.valueAt(i);
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now changing app %s", activity);
             activity.cancelAnimationOnly();
-            activity.applyAnimation(null, transit, true, false);
+            activity.applyAnimation(null, transit, true, false,
+                    null /* animationFinishedCallback */);
             activity.updateReportedVisibilityLocked();
             mService.openSurfaceTransaction();
             try {
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index af859d3..16aff9c 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -21,6 +21,7 @@
 import static com.android.server.wm.AlphaAnimationSpecProto.TO;
 import static com.android.server.wm.AnimationSpecProto.ALPHA;
 
+import android.annotation.Nullable;
 import android.graphics.Rect;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
@@ -156,7 +157,8 @@
     @VisibleForTesting
     interface SurfaceAnimatorStarter {
         void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
-                AnimationAdapter anim, boolean hidden);
+                AnimationAdapter anim, boolean hidden,
+                @Nullable Runnable animationFinishedCallback);
     }
 
     Dimmer(WindowContainer host) {
@@ -342,7 +344,8 @@
             SurfaceControl.Transaction t, float startAlpha, float endAlpha) {
         mSurfaceAnimatorStarter.startAnimation(animator, t, new LocalAnimationAdapter(
                 new AlphaAnimationSpec(startAlpha, endAlpha, getDimDuration(container)),
-                mHost.mWmService.mSurfaceAnimationRunner), false /* hidden */);
+                mHost.mWmService.mSurfaceAnimationRunner), false /* hidden */,
+                null /* animationFinishedCallback */);
     }
 
     private long getDimDuration(WindowContainer container) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 908c4f1..dbc9911 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -65,17 +65,15 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
@@ -168,8 +166,10 @@
 import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ActivityInfo.ScreenOrientation;
+import android.content.pm.ApplicationInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
@@ -219,6 +219,7 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.SurfaceSession;
 import android.view.View;
+import android.view.ViewRootImpl;
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
@@ -306,8 +307,8 @@
     // on the IME target. We mainly have this container grouping so we can keep track of all the IME
     // window containers together and move them in-sync if/when needed. We use a subclass of
     // WindowContainer which is omitted from screen magnification, as the IME is never magnified.
-    private final NonAppWindowContainers mImeWindowsContainers =
-            new NonAppWindowContainers("mImeWindowsContainers", mWmService);
+    // TODO(display-area): is "no magnification" in the comment still true?
+    private final ImeContainer mImeWindowsContainers = new ImeContainer(mWmService);
 
     private WindowState mTmpWindow;
     private WindowState mTmpWindow2;
@@ -400,14 +401,6 @@
     private int mCurrentOverrideConfigurationChanges;
 
     /**
-     * Orientation forced by some window. If there is no visible window that specifies orientation
-     * it is set to {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
-     *
-     * @see NonAppWindowContainers#getOrientation()
-     */
-    private int mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
-    /**
      * Last orientation forced by the keyguard. It is applied when keyguard is shown and is not
      * occluded.
      *
@@ -875,7 +868,7 @@
             if (w.mHasSurface && isDisplayed) {
                 final int type = w.mAttrs.type;
                 if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
-                        || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+                        || mWmService.mPolicy.isKeyguardShowing()) {
                     mTmpApplySurfaceChangesTransactionState.syswin = true;
                 }
                 if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0
@@ -1282,11 +1275,6 @@
         return mDisplayRotation.getLastOrientation();
     }
 
-    @ScreenOrientation
-    int getLastWindowForcedOrientation() {
-        return mLastWindowForcedOrientation;
-    }
-
     void registerRemoteAnimations(RemoteAnimationDefinition definition) {
         mAppTransitionController.registerRemoteAnimations(definition);
     }
@@ -2026,6 +2014,10 @@
         return mTaskStackContainers.getVisibleTasks();
     }
 
+    SurfaceControl getSplitScreenDividerAnchor() {
+        return mTaskStackContainers.getSplitScreenDividerAnchor();
+    }
+
     void onStackWindowingModeChanged(ActivityStack stack) {
         mTaskStackContainers.onStackWindowingModeChanged(stack);
     }
@@ -2112,7 +2104,7 @@
     }
 
     boolean forAllImeWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
-        return mImeWindowsContainers.forAllWindows(callback, traverseTopToBottom);
+        return mImeWindowsContainers.forAllWindowForce(callback, traverseTopToBottom);
     }
 
     /**
@@ -2129,16 +2121,7 @@
         }
 
         if (mWmService.mDisplayFrozen) {
-            if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-                ProtoLog.v(WM_DEBUG_ORIENTATION,
-                        "Display id=%d is frozen, return %d", mDisplayId,
-                        mLastWindowForcedOrientation);
-                // If the display is frozen, some activities may be in the middle of restarting, and
-                // thus have removed their old window. If the window has the flag to hide the lock
-                // screen, then the lock screen can re-appear and inflict its own orientation on us.
-                // Keep the orientation stable until this all settles down.
-                return mLastWindowForcedOrientation;
-            } else if (policy.isKeyguardLocked()) {
+            if (policy.isKeyguardLocked()) {
                 // Use the last orientation the while the display is frozen with the keyguard
                 // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
                 // window. We don't want to check the show when locked window directly though as
@@ -2149,11 +2132,10 @@
                         mDisplayId, getLastOrientation());
                 return getLastOrientation();
             }
-        } else {
-            final int orientation = mAboveAppWindowsContainers.getOrientation();
-            if (orientation != SCREEN_ORIENTATION_UNSET) {
-                return orientation;
-            }
+        }
+        final int orientation = mAboveAppWindowsContainers.getOrientation();
+        if (orientation != SCREEN_ORIENTATION_UNSET) {
+            return orientation;
         }
 
         // Top system windows are not requesting an orientation. Start searching from apps.
@@ -2370,11 +2352,15 @@
         throw new UnsupportedOperationException("See DisplayChildWindowContainer");
     }
 
+    void positionDisplayAt(int position, boolean includingParents) {
+        getParent().positionChildAt(position, this, includingParents);
+    }
+
     @Override
     void positionChildAt(int position, DisplayChildWindowContainer child, boolean includingParents) {
         // Children of the display are statically ordered, so the real intention here is to perform
         // the operation on the display and not the static direct children.
-        getParent().positionChildAt(position, this, includingParents);
+        positionDisplayAt(position, includingParents);
     }
 
     void positionStackAt(int position, ActivityStack child, boolean includingParents) {
@@ -3557,7 +3543,7 @@
         final SparseBooleanArray drawnWindowTypes = new SparseBooleanArray();
         // Presuppose keyguard is drawn because if its window isn't attached, we don't know if it
         // wants to be shown or hidden, then it should not delay enabling the screen.
-        drawnWindowTypes.put(TYPE_STATUS_BAR, true);
+        drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE, true);
 
         final WindowState visibleNotDrawnWindow = getWindow(w -> {
             if (w.mViewVisibility == View.VISIBLE && !w.mObscured && !w.isDrawnLw()) {
@@ -3568,8 +3554,9 @@
                 if (type == TYPE_BOOT_PROGRESS || type == TYPE_BASE_APPLICATION
                         || type == TYPE_WALLPAPER) {
                     drawnWindowTypes.put(type, true);
-                } else if (type == TYPE_STATUS_BAR) {
-                    drawnWindowTypes.put(TYPE_STATUS_BAR, mWmService.mPolicy.isKeyguardDrawnLw());
+                } else if (type == TYPE_NOTIFICATION_SHADE) {
+                    drawnWindowTypes.put(TYPE_NOTIFICATION_SHADE,
+                            mWmService.mPolicy.isKeyguardDrawnLw());
                 }
             }
             return false;
@@ -3591,7 +3578,7 @@
         final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
         final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
         final boolean haveWallpaper = drawnWindowTypes.get(TYPE_WALLPAPER);
-        final boolean haveKeyguard = drawnWindowTypes.get(TYPE_STATUS_BAR);
+        final boolean haveKeyguard = drawnWindowTypes.get(TYPE_NOTIFICATION_SHADE);
 
         ProtoLog.i(WM_DEBUG_SCREEN_ON,
                 "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b "
@@ -3689,7 +3676,8 @@
                     w.mSeq++;
                     w.mSystemUiVisibility = newValue;
                 }
-                if (newValue != curValue || w.mAttrs.hasSystemUiListeners) {
+                if ((newValue != curValue || w.mAttrs.hasSystemUiListeners)
+                        && ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
                     w.mClient.dispatchSystemUiVisibilityChanged(w.mSeq,
                             visibility, newValue, diff);
                 }
@@ -4130,6 +4118,8 @@
 
         DisplayChildWindowContainer(WindowManagerService service) {
             super(service);
+            // TODO(display-area): move to ConfigurationContainer?
+            mOrientation = SCREEN_ORIENTATION_UNSET;
         }
 
         @Override
@@ -4241,7 +4231,7 @@
         ArrayList<Task> getVisibleTasks() {
             final ArrayList<Task> visibleTasks = new ArrayList<>();
             forAllTasks(task -> {
-                if (task.isVisible()) {
+                if (!task.isRootTask() && task.isVisible()) {
                     visibleTasks.add(task);
                 }
             });
@@ -4260,36 +4250,48 @@
         private void addStackReferenceIfNeeded(ActivityStack stack) {
             if (stack.isActivityTypeHome()) {
                 if (mHomeStack != null) {
-                    throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
-                            + mHomeStack + " already exist on display=" + this + " stack=" + stack);
-
+                    if (!stack.isDescendantOf(mHomeStack)) {
+                        throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack="
+                                + mHomeStack + " already exist on display=" + this
+                                + " stack=" + stack);
+                    }
+                } else {
+                    mHomeStack = stack;
                 }
-                mHomeStack = stack;
             } else if (stack.isActivityTypeRecents()) {
                 if (mRecentsStack != null && mRecentsStack != stack) {
-                    throw new IllegalArgumentException(
-                        "addStackReferenceIfNeeded: recents stack=" + mRecentsStack
-                            + " already exist on display=" + this + " stack=" + stack);
+                    if (!stack.isDescendantOf(mRecentsStack)) {
+                        throw new IllegalArgumentException(
+                                "addStackReferenceIfNeeded: recents stack=" + mRecentsStack
+                                        + " already exist on display=" + this + " stack=" + stack);
+                    }
+                } else {
+                    mRecentsStack = stack;
                 }
-                mRecentsStack = stack;
             }
             final int windowingMode = stack.getWindowingMode();
             if (windowingMode == WINDOWING_MODE_PINNED) {
                 if (mPinnedStack != null) {
-                    throw new IllegalArgumentException("addStackReferenceIfNeeded: pinned stack="
-                            + mPinnedStack + " already exist on display=" + this
-                            + " stack=" + stack);
+                    if (!stack.isDescendantOf(mPinnedStack)) {
+                        throw new IllegalArgumentException(
+                                "addStackReferenceIfNeeded: pinned stack=" + mPinnedStack
+                                        + " already exist on display=" + this + " stack=" + stack);
+                    }
+                } else {
+                    mPinnedStack = stack;
                 }
-                mPinnedStack = stack;
             } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                 if (mSplitScreenPrimaryStack != null) {
-                    throw new IllegalArgumentException("addStackReferenceIfNeeded:"
-                            + " split-screen-primary" + " stack=" + mSplitScreenPrimaryStack
-                            + " already exist on display=" + this + " stack=" + stack);
+                    if (!stack.isDescendantOf(mSplitScreenPrimaryStack)) {
+                        throw new IllegalArgumentException("addStackReferenceIfNeeded:"
+                                + " split-screen-primary" + " stack=" + mSplitScreenPrimaryStack
+                                + " already exist on display=" + this + " stack=" + stack);
+                    }
+                } else {
+                    mSplitScreenPrimaryStack = stack;
+                    mDisplayContent.onSplitScreenModeActivated();
+                    mDividerControllerLocked.notifyDockedStackExistsChanged(true);
                 }
-                mSplitScreenPrimaryStack = stack;
-                mDisplayContent.onSplitScreenModeActivated();
-                mDividerControllerLocked.notifyDockedStackExistsChanged(true);
             }
         }
 
@@ -4338,8 +4340,9 @@
 
         @Override
         void positionChildAt(int position, ActivityStack child, boolean includingParents) {
-            if (child.getWindowConfiguration().isAlwaysOnTop()
-                    && position != POSITION_TOP && position != mChildren.size()) {
+            final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
+            final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
+            if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
                 // This stack is always-on-top, override the default behavior.
                 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
 
@@ -4355,18 +4358,14 @@
                 includingParents = false;
             }
             final int targetPosition = findPositionForStack(position, child, false /* adding */);
-            super.positionChildAt(targetPosition, child, includingParents);
+            super.positionChildAt(targetPosition, child, false /* includingParents */);
 
-            if (includingParents) {
-                // We still want to move the display of this stack container to top because even the
-                // target position is adjusted to non-top, the intention of the condition is to have
-                // higher z-order to gain focus (e.g. moving a task of a fullscreen stack to front
-                // in a non-top display which is using picture-in-picture mode).
-                final int topChildPosition = getChildCount() - 1;
-                if (targetPosition < topChildPosition && position >= topChildPosition) {
-                    getParent().positionChildAt(POSITION_TOP, this /* child */,
-                            true /* includingParents */);
-                }
+            if (includingParents && (moveToTop || moveToBottom)) {
+                // The DisplayContent children do not re-order, but we still want to move the
+                // display of this stack container because the intention of positioning is to have
+                // higher z-order to gain focus.
+                positionDisplayAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
+                        true /* includingParents */);
             }
 
             setLayoutNeeded();
@@ -4527,7 +4526,7 @@
         }
 
         @Override
-        int getOrientation() {
+        int getOrientation(int candidate) {
             if (isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
                 // Apps and their containers are not allowed to specify an orientation while the
                 // docked stack is visible...except for the home stack if the docked stack is
@@ -4545,7 +4544,7 @@
                 return SCREEN_ORIENTATION_UNSPECIFIED;
             }
 
-            final int orientation = super.getOrientation();
+            final int orientation = super.getOrientation(candidate);
             if (orientation != SCREEN_ORIENTATION_UNSET
                     && orientation != SCREEN_ORIENTATION_BEHIND) {
                 ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -4686,38 +4685,11 @@
         }
 
         @Override
-        SurfaceControl.Builder makeChildSurface(WindowContainer child) {
-            final SurfaceControl.Builder builder = super.makeChildSurface(child);
-            if (child instanceof WindowToken && ((WindowToken) child).mRoundedCornerOverlay) {
-                // To draw above the ColorFade layer during the screen off transition, the
-                // rounded corner overlays need to be at the root of the surface hierarchy.
-                // TODO: move the ColorLayer into the display overlay layer such that this is not
-                // necessary anymore.
-                builder.setParent(null);
-            }
-            return builder;
-        }
-
-        @Override
         void assignChildLayers(SurfaceControl.Transaction t) {
-            assignChildLayers(t, null /* imeContainer */);
-        }
-
-        void assignChildLayers(SurfaceControl.Transaction t, WindowContainer imeContainer) {
-            boolean needAssignIme = imeContainer != null
-                    && imeContainer.getSurfaceControl() != null;
+            boolean needAssignIme = mImeWindowsContainers.getSurfaceControl() != null;
             for (int j = 0; j < mChildren.size(); ++j) {
                 final WindowToken wt = mChildren.get(j);
 
-                // See {@link mSplitScreenDividerAnchor}
-                if (wt.windowType == TYPE_DOCK_DIVIDER) {
-                    wt.assignRelativeLayer(t, mTaskStackContainers.getSplitScreenDividerAnchor(), 1);
-                    continue;
-                }
-                if (wt.mRoundedCornerOverlay) {
-                    wt.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
-                    continue;
-                }
                 wt.assignLayer(t, j);
                 wt.assignChildLayers(t);
 
@@ -4726,13 +4698,10 @@
 
                 if (needAssignIme && layer >= mWmService.mPolicy.getWindowLayerFromTypeLw(
                         TYPE_INPUT_METHOD_DIALOG, true)) {
-                    imeContainer.assignRelativeLayer(t, wt.getSurfaceControl(), -1);
+                    mImeWindowsContainers.assignRelativeLayer(t, wt.getSurfaceControl(), -1);
                     needAssignIme = false;
                 }
             }
-            if (needAssignIme) {
-                imeContainer.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE);
-            }
         }
     }
 
@@ -4746,6 +4715,7 @@
 
         @Override
         void assignChildLayers(SurfaceControl.Transaction t) {
+            mImeWindowsContainers.setNeedsLayer();
             mBelowAppWindowsContainers.assignLayer(t, 0);
             mTaskStackContainers.assignLayer(t, 1);
             mAboveAppWindowsContainers.assignLayer(t, 2);
@@ -4781,15 +4751,14 @@
                         // TODO: We need to use an extra level on the app surface to ensure
                         // this is always above SurfaceView but always below attached window.
                         1);
-                needAssignIme = false;
             }
 
             // Above we have assigned layers to our children, now we ask them to assign
             // layers to their children.
             mBelowAppWindowsContainers.assignChildLayers(t);
             mTaskStackContainers.assignChildLayers(t);
-            mAboveAppWindowsContainers.assignChildLayers(t,
-                    needAssignIme ? mImeWindowsContainers : null);
+            mAboveAppWindowsContainers.assignChildLayers(t);
+            mImeWindowsContainers.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE);
             mImeWindowsContainers.assignChildLayers(t);
         }
 
@@ -4805,47 +4774,6 @@
             addChild(mImeWindowsContainers, null);
         }
 
-        /**
-         * In split-screen mode we process the IME containers above the docked divider
-         * rather than directly above their target.
-         */
-        private boolean skipTraverseChild(WindowContainer child) {
-            return child == mImeWindowsContainers && mInputMethodTarget != null
-                    && !hasSplitScreenPrimaryStack();
-        }
-
-        @Override
-        boolean forAllWindows(ToBooleanFunction<WindowState> callback,
-                boolean traverseTopToBottom) {
-            // Special handling so we can process IME windows with #forAllImeWindows above their IME
-            // target, or here in order if there isn't an IME target.
-            if (traverseTopToBottom) {
-                for (int i = mChildren.size() - 1; i >= 0; --i) {
-                    final WindowContainer child = mChildren.get(i);
-                    if (skipTraverseChild(child)) {
-                        continue;
-                    }
-
-                    if (child.forAllWindows(callback, traverseTopToBottom)) {
-                        return true;
-                    }
-                }
-            } else {
-                final int count = mChildren.size();
-                for (int i = 0; i < count; i++) {
-                    final WindowContainer child = mChildren.get(i);
-                    if (skipTraverseChild(child)) {
-                        continue;
-                    }
-
-                    if (child.forAllWindows(callback, traverseTopToBottom)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
         @Override
         void positionChildAt(int position, WindowContainer child, boolean includingParents) {
             // Children of the WindowContainers are statically ordered, so the real intention here
@@ -4871,11 +4799,25 @@
                         token2.mOwnerCanManageAppTokens) ? -1 : 1;
 
         private final Predicate<WindowState> mGetOrientingWindow = w -> {
-            if (!w.isVisibleLw() || !w.mLegacyPolicyVisibilityAfterAnim) {
-                return false;
+            final WindowManagerPolicy policy = mWmService.mPolicy;
+            if (policy.isKeyguardHostWindow(w.mAttrs)) {
+                if (mWmService.mKeyguardGoingAway) {
+                    return false;
+                }
+                // Consider unoccluding only when all unknown visibilities have been
+                // resolved, as otherwise we just may be starting another occluding activity.
+                final boolean isUnoccluding =
+                        mDisplayContent.mAppTransition.getAppTransition()
+                                == TRANSIT_KEYGUARD_UNOCCLUDE
+                                && mDisplayContent.mUnknownAppVisibilityController.allResolved();
+                // If keyguard is showing, or we're unoccluding, force the keyguard's orientation,
+                // even if SystemUI hasn't updated the attrs yet.
+                if (policy.isKeyguardShowingAndNotOccluded() || isUnoccluding) {
+                    return true;
+                }
             }
             final int req = w.mAttrs.screenOrientation;
-            if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND
+            if (req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND
                     || req == SCREEN_ORIENTATION_UNSET) {
                 return false;
             }
@@ -4902,39 +4844,27 @@
         }
 
         @Override
-        int getOrientation() {
-            final WindowManagerPolicy policy = mWmService.mPolicy;
+        int getOrientation(int candidate) {
             // Find a window requesting orientation.
             final WindowState win = getWindow(mGetOrientingWindow);
 
             if (win != null) {
-                final int req = win.mAttrs.screenOrientation;
-                if (policy.isKeyguardHostWindow(win.mAttrs)) {
-                    mLastKeyguardForcedOrientation = req;
-                    if (mWmService.mKeyguardGoingAway) {
-                        // Keyguard can't affect the orientation if it is going away...
-                        mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-                        return SCREEN_ORIENTATION_UNSET;
-                    }
-                }
+                int req = win.mAttrs.screenOrientation;
                 ProtoLog.v(WM_DEBUG_ORIENTATION,
                         "%s forcing orientation to %d for display id=%d", win, req,
                         mDisplayId);
-                return (mLastWindowForcedOrientation = req);
+                if (mWmService.mPolicy.isKeyguardHostWindow(win.mAttrs)) {
+                    // SystemUI controls the Keyguard orientation asynchronously, and mAttrs may be
+                    // stale. We record / use the last known override.
+                    if (req != SCREEN_ORIENTATION_UNSET && req != SCREEN_ORIENTATION_UNSPECIFIED) {
+                        mDisplayContent.mLastKeyguardForcedOrientation = req;
+                    } else {
+                        req = mDisplayContent.mLastKeyguardForcedOrientation;
+                    }
+                }
+                return req;
             }
-
-            mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
-            // Only allow force setting the orientation when all unknown visibilities have been
-            // resolved, as otherwise we just may be starting another occluding activity.
-            final boolean isUnoccluding =
-                    mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
-                            && mUnknownAppVisibilityController.allResolved();
-            if (policy.isKeyguardShowingAndNotOccluded() || isUnoccluding) {
-                return mLastKeyguardForcedOrientation;
-            }
-
-            return SCREEN_ORIENTATION_UNSET;
+            return candidate;
         }
 
         @Override
@@ -4959,6 +4889,74 @@
         }
     }
 
+    /**
+     * Container for IME windows.
+     *
+     * This has some special behaviors:
+     * - layers assignment is ignored except if setNeedsLayer() has been called before (and no
+     *   layer has been assigned since), to facilitate assigning the layer from the IME target, or
+     *   fall back if there is no target.
+     * - the container doesn't always participate in window traversal, according to
+     *   {@link #skipImeWindowsDuringTraversal()}
+     */
+    private class ImeContainer extends NonAppWindowContainers {
+        boolean mNeedsLayer = false;
+
+        ImeContainer(WindowManagerService wms) {
+            super("ImeContainer", wms);
+        }
+
+        public void setNeedsLayer() {
+            mNeedsLayer = true;
+        }
+
+        @Override
+        int getOrientation(int candidate) {
+            // IME does not participate in orientation.
+            return candidate;
+        }
+
+        @Override
+        boolean forAllWindows(ToBooleanFunction<WindowState> callback,
+                boolean traverseTopToBottom) {
+            final DisplayContent dc = mDisplayContent;
+            if (skipImeWindowsDuringTraversal(dc)) {
+                return false;
+            }
+            return super.forAllWindows(callback, traverseTopToBottom);
+        }
+
+        private boolean skipImeWindowsDuringTraversal(DisplayContent dc) {
+            // We skip IME windows so they're processed just above their target, except
+            // in split-screen mode where we process the IME containers above the docked divider.
+            return dc.mInputMethodTarget != null && !dc.hasSplitScreenPrimaryStack();
+        }
+
+        /** Like {@link #forAllWindows}, but ignores {@link #skipImeWindowsDuringTraversal} */
+        boolean forAllWindowForce(ToBooleanFunction<WindowState> callback,
+                boolean traverseTopToBottom) {
+            return super.forAllWindows(callback, traverseTopToBottom);
+        }
+
+        @Override
+        void assignLayer(Transaction t, int layer) {
+            if (!mNeedsLayer) {
+                return;
+            }
+            super.assignLayer(t, layer);
+            mNeedsLayer = false;
+        }
+
+        @Override
+        void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
+            if (!mNeedsLayer) {
+                return;
+            }
+            super.assignRelativeLayer(t, relativeTo, layer);
+            mNeedsLayer = false;
+        }
+    }
+
     @Override
     SurfaceSession getSession() {
         return mSession;
@@ -5062,6 +5060,7 @@
      * with {@link WindowState#assignLayer}
      */
     void assignRelativeLayerForImeTargetChild(SurfaceControl.Transaction t, WindowContainer child) {
+        mImeWindowsContainers.setNeedsLayer();
         child.assignRelativeLayer(t, mImeWindowsContainers.getSurfaceControl(), 1);
     }
 
@@ -5445,7 +5444,7 @@
                 SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
         final boolean stickyHideNav =
                 (sysUiVisibility & stickyHideNavFlags) == stickyHideNavFlags;
-        return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_STATUS_BAR
+        return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_NOTIFICATION_SHADE
                 && win.getActivityType() != ACTIVITY_TYPE_HOME;
     }
 
@@ -5738,6 +5737,10 @@
         return mAtmService.mStackSupervisor.getNextTaskIdForUser();
     }
 
+    ActivityStack createStack(int windowingMode, int activityType, boolean onTop) {
+        return createStack(windowingMode, activityType, onTop, null /*info*/, null /*intent*/);
+    }
+
     /**
      * Creates a stack matching the input windowing mode and activity type on this display.
      * @param windowingMode The windowing mode the stack should be created in. If
@@ -5749,13 +5752,14 @@
      * @param onTop If true the stack will be created at the top of the display, else at the bottom.
      * @return The newly created stack.
      */
-    ActivityStack createStack(int windowingMode, int activityType, boolean onTop) {
+    ActivityStack createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
+            Intent intent) {
         if (mSingleTaskInstance && getStackCount() > 0) {
             // Create stack on default display instead since this display can only contain 1 stack.
             // TODO: Kinda a hack, but better that having the decision at each call point. Hoping
             // this goes away once ActivityView is no longer using virtual displays.
             return mRootWindowContainer.getDefaultDisplay().createStack(
-                    windowingMode, activityType, onTop);
+                    windowingMode, activityType, onTop, info, intent);
         }
 
         if (activityType == ACTIVITY_TYPE_UNDEFINED) {
@@ -5783,18 +5787,23 @@
         }
 
         final int stackId = getNextStackId();
-        return createStackUnchecked(windowingMode, activityType, stackId, onTop);
+        return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent);
     }
 
     @VisibleForTesting
     ActivityStack createStackUnchecked(int windowingMode, int activityType,
-            int stackId, boolean onTop) {
+            int stackId, boolean onTop, ActivityInfo info, Intent intent) {
         if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) {
             throw new IllegalArgumentException("Stack with windowing mode cannot with non standard "
                     + "activity type.");
         }
+        if (info == null) {
+            info = new ActivityInfo();
+            info.applicationInfo = new ApplicationInfo();
+        }
+
         final ActivityStack stack = new ActivityStack(this, stackId,
-                mRootWindowContainer.mStackSupervisor, activityType);
+                mRootWindowContainer.mStackSupervisor, activityType, info, intent);
         addStack(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);
         stack.setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
                 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 9c62e99..2c325e5 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -58,11 +58,11 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ONLY_DRAW_BOTTOM_BAR_BACKGROUND;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
@@ -77,6 +77,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
 import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -289,6 +290,7 @@
 
     private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>();
     private WindowState mStatusBar = null;
+    private WindowState mNotificationShade = null;
     private final int[] mStatusBarHeightForRotation = new int[4];
     private WindowState mNavigationBar = null;
     @NavigationBarPosition
@@ -368,8 +370,6 @@
     private WindowState mTopDockedOpaqueOrDimmingWindowState;
     private boolean mTopIsFullscreen;
     private boolean mForceStatusBar;
-    private boolean mForceStatusBarFromKeyguard;
-    private boolean mForceStatusBarTransparent;
     private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
     private boolean mForcingShowNavBar;
     private int mForcingShowNavBarLayer;
@@ -851,15 +851,13 @@
                 // letterboxed. Hence always let them extend under the cutout.
                 attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                 break;
-            case TYPE_STATUS_BAR:
-
+            case TYPE_NOTIFICATION_SHADE:
                 // If the Keyguard is in a hidden state (occluded by another window), we force to
                 // remove the wallpaper and keyguard flag so that any change in-flight after setting
                 // the keyguard as occluded wouldn't set these flags again.
                 // See {@link #processKeyguardSetHiddenResultLw}.
                 if (mService.mPolicy.isKeyguardOccluded()) {
                     attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-                    attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
                 }
                 break;
 
@@ -891,11 +889,6 @@
                 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                 break;
         }
-
-        if (attrs.type != TYPE_STATUS_BAR) {
-            // The status bar is the only window allowed to exhibit keyguard behavior.
-            attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-        }
     }
 
     /**
@@ -914,6 +907,7 @@
      * Currently enforces that two window types are singletons per display:
      * <ul>
      * <li>{@link WindowManager.LayoutParams#TYPE_STATUS_BAR}</li>
+     * <li>{@link WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}</li>
      * <li>{@link WindowManager.LayoutParams#TYPE_NAVIGATION_BAR}</li>
      * </ul>
      *
@@ -940,6 +934,16 @@
                     }
                 }
                 break;
+            case TYPE_NOTIFICATION_SHADE:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                        "DisplayPolicy");
+                if (mNotificationShade != null) {
+                    if (mNotificationShade.isAlive()) {
+                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+                    }
+                }
+                break;
             case TYPE_NAVIGATION_BAR:
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE,
@@ -974,12 +978,15 @@
         }
 
         switch (attrs.type) {
-            case TYPE_STATUS_BAR:
-                mStatusBar = win;
-                mStatusBarController.setWindow(win);
+            case TYPE_NOTIFICATION_SHADE:
+                mNotificationShade = win;
                 if (mDisplayContent.isDefaultDisplay) {
                     mService.mPolicy.setKeyguardCandidateLw(win);
                 }
+                break;
+            case TYPE_STATUS_BAR:
+                mStatusBar = win;
+                mStatusBarController.setWindow(win);
                 final TriConsumer<DisplayFrames, WindowState, Rect> frameProvider =
                         (displayFrames, windowState, rect) -> {
                             rect.top = 0;
@@ -1036,14 +1043,16 @@
         if (mStatusBar == win) {
             mStatusBar = null;
             mStatusBarController.setWindow(null);
-            if (mDisplayContent.isDefaultDisplay) {
-                mService.mPolicy.setKeyguardCandidateLw(null);
-            }
             mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null);
         } else if (mNavigationBar == win) {
             mNavigationBar = null;
             mNavigationBarController.setWindow(null);
             mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null);
+        } else if (mNotificationShade == win) {
+            mNotificationShade = null;
+            if (mDisplayContent.isDefaultDisplay) {
+                mService.mPolicy.setKeyguardCandidateLw(null);
+            }
         }
         if (mLastFocusedWindow == win) {
             mLastFocusedWindow = null;
@@ -1060,6 +1069,10 @@
         return mStatusBar;
     }
 
+    WindowState getNotificationShade() {
+        return mNotificationShade;
+    }
+
     WindowState getNavigationBar() {
         return mNavigationBar;
     }
@@ -1082,12 +1095,6 @@
         if (DEBUG_ANIM) Slog.i(TAG, "selectAnimation in " + win
                 + ": transit=" + transit);
         if (win == mStatusBar) {
-            final boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
-            final boolean expanded = win.getAttrs().height == MATCH_PARENT
-                    && win.getAttrs().width == MATCH_PARENT;
-            if (isKeyguard || expanded) {
-                return ANIMATION_NONE;
-            }
             if (transit == TRANSIT_EXIT
                     || transit == TRANSIT_HIDE) {
                 return R.anim.dock_top_exit;
@@ -1425,10 +1432,10 @@
                 || (behavior & BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) != 0;
         boolean navAllowedHidden = immersive || immersiveSticky;
         navTranslucent &= !immersiveSticky;  // transient trumps translucent
-        boolean isKeyguardShowing = isStatusBarKeyguard()
-                && !mService.mPolicy.isKeyguardOccluded();
-        boolean statusBarForcesShowingNavigation = !isKeyguardShowing && mStatusBar != null
-                && (mStatusBar.getAttrs().privateFlags
+        boolean isKeyguardShowing = isKeyguardShowing() && !isKeyguardOccluded();
+        boolean notificationShadeForcesShowingNavigation =
+                !isKeyguardShowing && mNotificationShade != null
+                && (mNotificationShade.getAttrs().privateFlags
                 & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
 
         // When the navigation bar isn't visible, we put up a fake input window to catch all
@@ -1455,7 +1462,7 @@
         navVisible |= !canHideNavigationBar();
 
         boolean updateSysUiVisibility = layoutNavigationBar(displayFrames, uiMode, navVisible,
-                navTranslucent, navAllowedHidden, statusBarForcesShowingNavigation);
+                navTranslucent, navAllowedHidden, notificationShadeForcesShowingNavigation);
         if (DEBUG_LAYOUT) Slog.i(TAG, "mDock rect:" + displayFrames.mDock);
         updateSysUiVisibility |= layoutStatusBar(displayFrames, sysui, isKeyguardShowing);
         if (updateSysUiVisibility) {
@@ -2104,7 +2111,7 @@
                     df.set(displayFrames.mUnrestricted);
                     pf.set(displayFrames.mUnrestricted);
                 } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
-                        && (type == TYPE_STATUS_BAR
+                        && (type == TYPE_NOTIFICATION_SHADE
                         || type == TYPE_TOAST
                         || type == TYPE_DOCK_DIVIDER
                         || type == TYPE_VOICE_INTERACTION_STARTING
@@ -2210,7 +2217,8 @@
 
         // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
         // the cutout safe zone.
-        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) {
+        if (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
+                || cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
             final Rect displayCutoutSafeExceptMaybeBars = sTmpDisplayCutoutSafeExceptMaybeBarsRect;
             displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
             if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
@@ -2355,8 +2363,6 @@
         mTopDockedOpaqueWindowState = null;
         mTopDockedOpaqueOrDimmingWindowState = null;
         mForceStatusBar = false;
-        mForceStatusBarFromKeyguard = false;
-        mForceStatusBarTransparent = false;
         mForcingShowNavBar = false;
         mForcingShowNavBarLayer = -1;
 
@@ -2384,14 +2390,6 @@
             mForcingShowNavBar = true;
             mForcingShowNavBarLayer = win.getSurfaceLayer();
         }
-        if (attrs.type == TYPE_STATUS_BAR) {
-            if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-                mForceStatusBarFromKeyguard = true;
-            }
-            if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
-                mForceStatusBarTransparent = true;
-            }
-        }
 
         boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
                 && attrs.type < FIRST_SYSTEM_WINDOW;
@@ -2513,32 +2511,25 @@
 
         if (mStatusBar != null) {
             if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar
-                    + " forcefkg=" + mForceStatusBarFromKeyguard
                     + " top=" + mTopFullscreenOpaqueWindowState);
-            boolean shouldBeTransparent = mForceStatusBarTransparent
-                    && !mForceStatusBar
-                    && !mForceStatusBarFromKeyguard;
-            if (!shouldBeTransparent) {
-                mStatusBarController.setShowTransparent(false /* transparent */);
-            } else if (!mStatusBar.isVisibleLw()) {
-                mStatusBarController.setShowTransparent(true /* transparent */);
-            }
-
-            boolean statusBarForcesShowingNavigation =
-                    (mStatusBar.getAttrs().privateFlags
+            final boolean forceShowStatusBar = (mStatusBar.getAttrs().privateFlags
+                    & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0;
+            final boolean notificationShadeForcesShowingNavigation =
+                    mNotificationShade != null
+                            && (mNotificationShade.getAttrs().privateFlags
                             & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
+
             boolean topAppHidesStatusBar = topAppHidesStatusBar();
-            if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent
-                    || statusBarForcesShowingNavigation) {
+            if (mForceStatusBar || forceShowStatusBar) {
                 if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced");
                 if (mStatusBarController.setBarShowingLw(true)) {
                     changes |= FINISH_LAYOUT_REDO_LAYOUT;
                 }
                 // Maintain fullscreen layout until incoming animation is complete.
                 topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw();
-                // Transient status bar is not allowed if status bar is on lockscreen or status bar
-                // is expecting the navigation keys from the user.
-                if ((mForceStatusBarFromKeyguard || statusBarForcesShowingNavigation)
+                // Transient status bar is not allowed if notification shade is expecting the
+                // navigation keys from the user.
+                if (notificationShadeForcesShowingNavigation
                         && mStatusBarController.isTransientShowing()) {
                     mStatusBarController.updateVisibilityLw(false /*transientAllowed*/,
                             mLastSystemUiFlags, mLastSystemUiFlags);
@@ -3102,11 +3093,9 @@
         }
     }
 
-    private boolean isStatusBarKeyguard() {
-        return mStatusBar != null
-                && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
+    boolean isKeyguardShowing() {
+        return mService.mPolicy.isKeyguardShowing();
     }
-
     private boolean isKeyguardOccluded() {
         // TODO (b/113840485): Handle per display keyguard.
         return mService.mPolicy.isKeyguardOccluded();
@@ -3139,7 +3128,7 @@
             // keys, we let it keep controlling the visibility.
             final boolean lastFocusCanReceiveKeys =
                     (mLastFocusedWindow != null && mLastFocusedWindow.canReceiveKeys());
-            winCandidate = isStatusBarKeyguard() ? mStatusBar
+            winCandidate = isKeyguardShowing() ? mNotificationShade
                     : lastFocusCanReceiveKeys ? mLastFocusedWindow
                             : mTopFullscreenOpaqueWindowState;
             if (winCandidate == null) {
@@ -3147,7 +3136,8 @@
             }
         }
         final WindowState win = winCandidate;
-        if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && isKeyguardOccluded()) {
+        if (win.getAttrs().type == TYPE_NOTIFICATION_SHADE && isKeyguardShowing()
+                && isKeyguardOccluded()) {
             // We are updating at a point where the keyguard has gotten
             // focus, but we were last in a state where the top window is
             // hiding it.  This is probably because the keyguard as been
@@ -3281,8 +3271,8 @@
 
     private int updateLightStatusBarAppearanceLw(@Appearance int appearance, WindowState opaque,
             WindowState opaqueOrDimming) {
-        final boolean onKeyguard = isStatusBarKeyguard() && !isKeyguardOccluded();
-        final WindowState statusColorWin = onKeyguard ? mStatusBar : opaqueOrDimming;
+        final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded();
+        final WindowState statusColorWin = onKeyguard ? mNotificationShade : opaqueOrDimming;
         if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
             // If the top fullscreen-or-dimming window is also the top fullscreen, respect
             // its light flag.
@@ -3370,11 +3360,11 @@
         // visibility changes.
         mForceShowSystemBars = dockedStackVisible || win.inFreeformWindowingMode() || resizing
                 || mForceShowSystemBarsFromExternal;
-        final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;
+        final boolean forceOpaqueStatusBar = mForceShowSystemBars && !isKeyguardShowing();
 
         // apply translucent bar vis flags
-        WindowState fullscreenTransWin = isStatusBarKeyguard() && !isKeyguardOccluded()
-                ? mStatusBar
+        WindowState fullscreenTransWin = isKeyguardShowing() && !isKeyguardOccluded()
+                ? mNotificationShade
                 : mTopFullscreenOpaqueWindowState;
         vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
         vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
@@ -3394,8 +3384,8 @@
 
         // prevent status bar interaction from clearing certain flags
         int type = win.getAttrs().type;
-        boolean statusBarHasFocus = type == TYPE_STATUS_BAR;
-        if (statusBarHasFocus && !isStatusBarKeyguard()) {
+        boolean notificationShadeHasFocus = type == TYPE_NOTIFICATION_SHADE;
+        if (notificationShadeHasFocus && !isKeyguardShowing()) {
             int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
                     | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                     | View.SYSTEM_UI_FLAG_IMMERSIVE
@@ -3430,7 +3420,7 @@
                 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
 
         final boolean transientStatusBarAllowed = mStatusBar != null
-                && (statusBarHasFocus || (!mForceShowSystemBars
+                && (notificationShadeHasFocus || (!mForceShowSystemBars
                 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky))));
 
         final boolean transientNavBarAllowed = mNavigationBar != null
@@ -3441,7 +3431,7 @@
                 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
         final DisplayPolicy defaultDisplayPolicy =
                 mService.getDefaultDisplayContentLocked().getDisplayPolicy();
-        if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard()
+        if (pendingPanic && hideNavBarSysui && !isKeyguardShowing()
                 // TODO (b/111955725): Show keyguard presentation on all external displays
                 && defaultDisplayPolicy.isKeyguardDrawComplete()) {
             // The user performed the panic gesture recently, we're about to hide the bars,
@@ -3703,8 +3693,11 @@
         pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
         if (mStatusBar != null) {
             pw.print(prefix); pw.print("mStatusBar="); pw.print(mStatusBar);
-                    pw.print(" isStatusBarKeyguard="); pw.println(isStatusBarKeyguard());
         }
+        if (mNotificationShade != null) {
+            pw.print(prefix); pw.print("mExpandedPanel="); pw.print(mNotificationShade);
+        }
+        pw.print(" isKeyguardShowing="); pw.println(isKeyguardShowing());
         if (mNavigationBar != null) {
             pw.print(prefix); pw.print("mNavigationBar="); pw.println(mNavigationBar);
             pw.print(prefix); pw.print("mNavBarOpacityMode="); pw.println(mNavBarOpacityMode);
@@ -3733,7 +3726,6 @@
         }
         pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen);
         pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
-        pw.print(" mForceStatusBarFromKeyguard="); pw.println(mForceStatusBarFromKeyguard);
         pw.print(prefix); pw.print("mForceShowSystemBarsFromExternal=");
         pw.print(mForceShowSystemBarsFromExternal);
         pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 091f66c..4c5914b 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -23,7 +23,6 @@
 import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
@@ -527,7 +526,7 @@
                 mDisableWallpaperTouchEvents = true;
             }
             final boolean hasWallpaper = wallpaperController.isWallpaperTarget(w)
-                    && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
+                    && !mService.mPolicy.isKeyguardShowing()
                     && !mDisableWallpaperTouchEvents;
 
             // If there's a drag in progress and 'child' is a potential drop target,
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index a008963..fa764e3 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -22,8 +22,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
 
 import android.annotation.Nullable;
@@ -188,7 +187,7 @@
         if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
             return mTransientControlTarget;
         }
-        if (areSystemBarsForciblyVisible() || isStatusBarForciblyVisible()) {
+        if (areSystemBarsForciblyVisible() || isKeyguardOrStatusBarForciblyVisible()) {
             return null;
         }
         return focusedWin;
@@ -204,29 +203,27 @@
         return focusedWin;
     }
 
-    private boolean isStatusBarForciblyVisible() {
+    private boolean isKeyguardOrStatusBarForciblyVisible() {
+        if (mPolicy.isKeyguardShowing()) {
+            return true;
+        }
         final WindowState statusBar = mPolicy.getStatusBar();
-        if (statusBar == null) {
-            return false;
-        }
-        final int privateFlags = statusBar.mAttrs.privateFlags;
-
-        // TODO(b/118118435): Pretend to the app that it's still able to control it?
-        if ((privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
-            return true;
-        }
-        if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-            return true;
+        if (statusBar != null) {
+            // TODO(b/118118435): Pretend to the app that it's still able to control it?
+            if ((statusBar.mAttrs.privateFlags & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0) {
+                return true;
+            }
         }
         return false;
     }
 
     private boolean isNavBarForciblyVisible() {
-        final WindowState statusBar = mPolicy.getStatusBar();
-        if (statusBar == null) {
+        final WindowState notificationShade = mPolicy.getNotificationShade();
+        if (notificationShade == null) {
             return false;
         }
-        if ((statusBar.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0) {
+        if ((notificationShade.mAttrs.privateFlags
+                & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0) {
             return true;
         }
         return false;
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 5df80fc..e1dfc17 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -32,7 +32,6 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.os.Process.SYSTEM_UID;
-import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
@@ -1382,7 +1381,7 @@
 
         // Ignore tasks from different displays
         // TODO (b/115289124): No Recents on non-default displays.
-        if (stack.getDisplayId() != DEFAULT_DISPLAY) {
+        if (!stack.isOnHomeDisplay()) {
             return false;
         }
 
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index b255b5e..6148095 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -374,7 +374,7 @@
             final PooledConsumer c = PooledLambda.obtainConsumer((t, outList) ->
 	            { if (!outList.contains(t)) outList.add(t); }, PooledLambda.__(Task.class),
                     visibleTasks);
-            targetStack.forAllTasks(c);
+            targetStack.forAllTasks(c, true /* traverseTopToBottom */, targetStack);
             c.recycle();
         }
 
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index e310fc1..2f61ca0 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -247,8 +247,7 @@
             } else {
                 targetTask = mTargetStack.createTask(
                         atmService.mStackSupervisor.getNextTaskIdForUser(r.mUserId), r.info,
-                        null /* intent */, null /* voiceSession */, null /* voiceInteractor */,
-                        false /* toTop */);
+                        null /* intent */, false /* toTop */);
                 targetTask.affinityIntent = r.intent;
                 createdTasks.add(targetTask);
                 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity "
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2f726e9..8202833 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -35,7 +35,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
@@ -1147,7 +1146,7 @@
                 // While a dream or keyguard is showing, obscure ordinary application content on
                 // secondary displays (by forcibly enabling mirroring unless there is other content
                 // we want to show) but still allow opaque keyguard dialogs to be shown.
-                if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+                if (type == TYPE_DREAM || mWmService.mPolicy.isKeyguardShowing()) {
                     mObscureApplicationContentOnSecondaryDisplays = true;
                 }
                 displayHasContent = true;
@@ -2132,23 +2131,13 @@
                 // We will then perform a windowing mode change for both scenarios.
                 stack = display.createStack(
                         r.getActivityStack().getRequestedOverrideWindowingMode(),
-                        r.getActivityType(), ON_TOP);
+                        r.getActivityType(), ON_TOP, r.info, r.intent);
                 // There are multiple activities in the task and moving the top activity should
                 // reveal/leave the other activities in their original task.
 
-                // Currently, we don't support reparenting activities across tasks in two different
-                // stacks, so instead, just create a new task in the same stack, reparent the
-                // activity into that task, and then reparent the whole task to the new stack. This
-                // ensures that all the necessary work to migrate states in the old and new stacks
-                // is also done.
-                final Task newTask = task.getStack().createTask(
-                        mStackSupervisor.getNextTaskIdForUser(r.mUserId), r.info,
-                        r.intent, null, null, true);
+                Task newTask = stack.createTask(mStackSupervisor.getNextTaskIdForUser(r.mUserId),
+                        r.info, r.intent, true);
                 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
-
-                // Defer resume until below, and do not schedule PiP changes until we animate below
-                newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
-                        DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
             }
 
             stack.setWindowingMode(WINDOWING_MODE_PINNED);
@@ -2417,17 +2406,17 @@
         info.position = display != null ? display.getIndexOf(stack) : 0;
         info.configuration.setTo(stack.getConfiguration());
 
-        final int numTasks = stack.getChildCount();
+        final int numTasks = stack.getDescendantTaskCount();
         info.taskIds = new int[numTasks];
         info.taskNames = new String[numTasks];
         info.taskBounds = new Rect[numTasks];
         info.taskUserIds = new int[numTasks];
-        final int[] currenIndex = {0};
+        final int[] currentIndex = {0};
 
         final PooledConsumer c = PooledLambda.obtainConsumer(
                 RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
-                currenIndex);
-        stack.forAllTasks(c, false);
+                currentIndex);
+        stack.forAllTasks(c, false /* traverseTopToBottom */, stack);
         c.recycle();
 
         final ActivityRecord top = stack.topRunningActivity();
@@ -2570,7 +2559,7 @@
     }
 
     ActivityStack findStackBehind(ActivityStack stack) {
-        final DisplayContent display = getDisplayContent(stack.getDisplayId());
+        final DisplayContent display = stack.getDisplayContent();
         if (display != null) {
             for (int i = display.getStackCount() - 1; i >= 0; i--) {
                 if (display.getStackAt(i) == stack && i > 0) {
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 98127ab..6ebbf77 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -93,6 +93,9 @@
     }
 
     private void processTask(Task task) {
+        if (task.isRootTask()) {
+            return;
+        }
         if (task.getTopNonFinishingActivity() == null) {
             // Skip if there are no activities in the task
             return;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 399c5d3..bfb69172 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -16,8 +16,12 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.AnimationSpecProto.ROTATE;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.RotationAnimationSpecProto.DURATION_MS;
+import static com.android.server.wm.RotationAnimationSpecProto.END_LUMA;
+import static com.android.server.wm.RotationAnimationSpecProto.START_LUMA;
 import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING;
 import static com.android.server.wm.ScreenRotationAnimationProto.STARTED;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -25,7 +29,9 @@
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
 
+import android.animation.ArgbEvaluator;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -40,7 +46,9 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
 
+import com.android.internal.R;
 import com.android.server.protolog.common.ProtoLog;
+import com.android.server.wm.utils.RotationAnimationUtils;
 
 import java.io.PrintWriter;
 
@@ -60,10 +68,10 @@
  *      animation first rotate the new content into the old orientation to then be able to
  *      animate to the new orientation
  *
- * <li> The exiting Blackframe: <p>
- *     Because the change of orientation might change the width and height of the content (i.e
- *     when rotating from portrait to landscape) we "crop" the new content using black frames
- *     around the screenshot so the new content does not go beyond the screenshot's bounds
+ * <li> The Background color frame: <p>
+ *      To have the animation seem more seamless, we add a color transitioning background behind the
+ *      exiting and entering layouts. We compute the brightness of the start and end
+ *      layouts and transition from the two brightness values as grayscale underneath the animation
  *
  * <li> The entering Blackframe: <p>
  *     The enter Blackframe is similar to the exit Blackframe but is only used when a custom
@@ -81,8 +89,6 @@
      */
     private static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
     private static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
-    private static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
-    private static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;
 
     private final Context mContext;
     private final DisplayContent mDisplayContent;
@@ -90,16 +96,18 @@
     private final Transformation mRotateExitTransformation = new Transformation();
     private final Transformation mRotateEnterTransformation = new Transformation();
     // Complete transformations being applied.
-    private final Transformation mExitTransformation = new Transformation();
     private final Transformation mEnterTransformation = new Transformation();
-    private final Matrix mFrameInitialMatrix = new Matrix();
     private final Matrix mSnapshotInitialMatrix = new Matrix();
-    private final Matrix mSnapshotFinalMatrix = new Matrix();
-    private final Matrix mExitFrameFinalMatrix = new Matrix();
     private final WindowManagerService mService;
+    /** Only used for custom animations and not screen rotation. */
     private SurfaceControl mEnterBlackFrameLayer;
-    private SurfaceControl mRotationLayer;
-    private SurfaceControl mSurfaceControl;
+    /** This layer contains the actual screenshot that is to be faded out. */
+    private SurfaceControl mScreenshotLayer;
+    /**
+     * Only used for screen rotation and not custom animations. Layered behind all other layers
+     * to avoid showing any "empty" spots
+     */
+    private SurfaceControl mBackColorSurface;
     private BlackFrame mEnteringBlackFrame;
     private int mWidth, mHeight;
 
@@ -120,8 +128,11 @@
     private boolean mFinishAnimReady;
     private long mFinishAnimStartTime;
     private boolean mForceDefaultOrientation;
-    private BlackFrame mExitingBlackFrame;
     private SurfaceRotationAnimationController mSurfaceRotationAnimationController;
+    /** Intensity of light/whiteness of the layout before rotation occurs. */
+    private float mStartLuma;
+    /** Intensity of light/whiteness of the layout after rotation occurs. */
+    private float mEndLuma;
 
     public ScreenRotationAnimation(Context context, DisplayContent displayContent,
             boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) {
@@ -162,9 +173,15 @@
 
         final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
         try {
-            mRotationLayer = displayContent.makeOverlay()
+            mBackColorSurface = displayContent.makeChildSurface(null)
+                    .setName("BackColorSurface")
+                    .setColorLayer()
+                    .build();
+
+            mScreenshotLayer = displayContent.makeOverlay()
                     .setName("RotationLayer")
-                    .setContainerLayer()
+                    .setBufferSize(mWidth, mHeight)
+                    .setSecure(isSecure)
                     .build();
 
             mEnterBlackFrameLayer = displayContent.makeOverlay()
@@ -172,26 +189,21 @@
                     .setContainerLayer()
                     .build();
 
-            mSurfaceControl = mService.makeSurfaceBuilder(null)
-                    .setName("ScreenshotSurface")
-                    .setParent(mRotationLayer)
-                    .setBufferSize(mWidth, mHeight)
-                    .setSecure(isSecure)
-                    .build();
-
             // In case display bounds change, screenshot buffer and surface may mismatch so set a
             // scaling mode.
             SurfaceControl.Transaction t2 = mService.mTransactionFactory.get();
-            t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW);
+            t2.setOverrideScalingMode(mScreenshotLayer, Surface.SCALING_MODE_SCALE_TO_WINDOW);
             t2.apply(true /* sync */);
 
             // Capture a screenshot into the surface we just created.
             final int displayId = display.getDisplayId();
             final Surface surface = mService.mSurfaceFactory.get();
-            surface.copyFrom(mSurfaceControl);
+            surface.copyFrom(mScreenshotLayer);
             SurfaceControl.ScreenshotGraphicBuffer gb =
                     mService.mDisplayManagerInternal.screenshot(displayId);
             if (gb != null) {
+                mStartLuma = RotationAnimationUtils.getAvgBorderLuma(gb.getGraphicBuffer(),
+                        gb.getColorSpace());
                 try {
                     surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
                             gb.getColorSpace());
@@ -202,13 +214,15 @@
                 // screenshot surface we display it in also has FLAG_SECURE so that
                 // the user can not screenshot secure layers via the screenshot surface.
                 if (gb.containsSecureLayers()) {
-                    t.setSecure(mSurfaceControl, true);
+                    t.setSecure(mScreenshotLayer, true);
                 }
-                t.setLayer(mRotationLayer, SCREEN_FREEZE_LAYER_BASE);
-                t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
-                t.setAlpha(mSurfaceControl, 0);
-                t.show(mRotationLayer);
-                t.show(mSurfaceControl);
+                t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE);
+                t.reparent(mBackColorSurface, displayContent.getSurfaceControl());
+                t.setLayer(mBackColorSurface, -1);
+                t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma});
+                t.setAlpha(mBackColorSurface, 1);
+                t.show(mScreenshotLayer);
+                t.show(mBackColorSurface);
             } else {
                 Slog.w(TAG, "Unable to take screenshot of display " + displayId);
             }
@@ -218,32 +232,11 @@
         }
 
         ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
-                    "  FREEZE %s: CREATE", mSurfaceControl);
+                    "  FREEZE %s: CREATE", mScreenshotLayer);
         setRotation(t, originalRotation);
         t.apply();
     }
 
-    private static void createRotationMatrix(int rotation, int width, int height,
-            Matrix outMatrix) {
-        switch (rotation) {
-            case Surface.ROTATION_0:
-                outMatrix.reset();
-                break;
-            case Surface.ROTATION_90:
-                outMatrix.setRotate(90, 0, 0);
-                outMatrix.postTranslate(height, 0);
-                break;
-            case Surface.ROTATION_180:
-                outMatrix.setRotate(180, 0, 0);
-                outMatrix.postTranslate(width, height);
-                break;
-            case Surface.ROTATION_270:
-                outMatrix.setRotate(270, 0, 0);
-                outMatrix.postTranslate(0, width);
-                break;
-        }
-    }
-
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(STARTED, mStarted);
@@ -252,11 +245,11 @@
     }
 
     boolean hasScreenshot() {
-        return mSurfaceControl != null;
+        return mScreenshotLayer != null;
     }
 
     private void setRotationTransform(SurfaceControl.Transaction t, Matrix matrix) {
-        if (mRotationLayer == null) {
+        if (mScreenshotLayer == null) {
             return;
         }
         matrix.getValues(mTmpFloats);
@@ -267,24 +260,19 @@
             x -= mCurrentDisplayRect.left;
             y -= mCurrentDisplayRect.top;
         }
-        t.setPosition(mRotationLayer, x, y);
-        t.setMatrix(mRotationLayer,
+        t.setPosition(mScreenshotLayer, x, y);
+        t.setMatrix(mScreenshotLayer,
                 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
 
-        t.setAlpha(mSurfaceControl, (float) 1.0);
-        t.setAlpha(mRotationLayer, (float) 1.0);
-        t.show(mRotationLayer);
+        t.setAlpha(mScreenshotLayer, (float) 1.0);
+        t.show(mScreenshotLayer);
     }
 
     public void printTo(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
+        pw.print(prefix); pw.print("mSurface="); pw.print(mScreenshotLayer);
         pw.print(" mWidth="); pw.print(mWidth);
         pw.print(" mHeight="); pw.println(mHeight);
-        pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
-        if (mExitingBlackFrame != null) {
-            mExitingBlackFrame.printTo(prefix + "  ", pw);
-        }
         pw.print(prefix);
         pw.print("mEnteringBlackFrame=");
         pw.println(mEnteringBlackFrame);
@@ -303,20 +291,10 @@
         pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
         pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
         pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
-        pw.print(prefix); pw.print("mExitTransformation=");
-        mExitTransformation.printShortString(pw); pw.println();
         pw.print(prefix); pw.print("mEnterTransformation=");
         mEnterTransformation.printShortString(pw); pw.println();
-        pw.print(prefix); pw.print("mFrameInitialMatrix=");
-        mFrameInitialMatrix.printShortString(pw);
-        pw.println();
         pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
-        mSnapshotInitialMatrix.printShortString(pw);
-        pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
-        pw.println();
-        pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
-        mExitFrameFinalMatrix.printShortString(pw);
-        pw.println();
+        mSnapshotInitialMatrix.printShortString(pw);pw.println();
         pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
         if (mForceDefaultOrientation) {
             pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
@@ -331,7 +309,7 @@
         // to the snapshot to make it stay in the same original position
         // with the current screen rotation.
         int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
-        createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
+        RotationAnimationUtils.createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
 
         setRotationTransform(t, mSnapshotInitialMatrix);
     }
@@ -341,7 +319,7 @@
      */
     private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration,
             float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
-        if (mSurfaceControl == null) {
+        if (mScreenshotLayer == null) {
             // Can't do animation.
             return false;
         }
@@ -354,89 +332,58 @@
         // Figure out how the screen has moved from the original rotation.
         int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
 
-        mRotateAlphaAnimation = AnimationUtils.loadAnimation(mContext,
-                com.android.internal.R.anim.screen_rotate_alpha);
 
         final boolean customAnim;
         if (exitAnim != 0 && enterAnim != 0) {
             customAnim = true;
             mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
             mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
+            mRotateAlphaAnimation = AnimationUtils.loadAnimation(mContext,
+                    R.anim.screen_rotate_alpha);
         } else {
             customAnim = false;
-            switch (delta) {
+            switch (delta) { /* Counter-Clockwise Rotations */
                 case Surface.ROTATION_0:
                     mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_0_exit);
+                            R.anim.screen_rotate_0_exit);
                     mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_0_enter);
+                            R.anim.screen_rotate_0_enter);
                     break;
                 case Surface.ROTATION_90:
                     mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_plus_90_exit);
+                            R.anim.screen_rotate_plus_90_exit);
                     mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_plus_90_enter);
+                            R.anim.screen_rotate_plus_90_enter);
                     break;
                 case Surface.ROTATION_180:
                     mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_180_exit);
+                            R.anim.screen_rotate_180_exit);
                     mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_180_enter);
+                            R.anim.screen_rotate_180_enter);
                     break;
                 case Surface.ROTATION_270:
                     mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_minus_90_exit);
+                            R.anim.screen_rotate_minus_90_exit);
                     mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.screen_rotate_minus_90_enter);
+                            R.anim.screen_rotate_minus_90_enter);
                     break;
             }
         }
 
-        // Initialize the animations.  This is a hack, redefining what "parent"
-        // means to allow supplying the last and next size.  In this definition
-        // "%p" is the original (let's call it "previous") size, and "%" is the
-        // screen's current/new size.
-        mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
         mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
+        mRotateExitAnimation.restrictDuration(maxAnimationDuration);
+        mRotateExitAnimation.scaleCurrentDuration(animationScale);
+        mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
+        mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
+        mRotateEnterAnimation.scaleCurrentDuration(animationScale);
+
         mAnimRunning = false;
         mFinishAnimReady = false;
         mFinishAnimStartTime = -1;
 
-        mRotateExitAnimation.restrictDuration(maxAnimationDuration);
-        mRotateExitAnimation.scaleCurrentDuration(animationScale);
-        mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
-        mRotateEnterAnimation.scaleCurrentDuration(animationScale);
-        mRotateAlphaAnimation.restrictDuration(maxAnimationDuration);
-        mRotateAlphaAnimation.scaleCurrentDuration(animationScale);
-
-        if (!customAnim && mExitingBlackFrame == null) {
-            try {
-                // Compute the transformation matrix that must be applied
-                // the the black frame to make it stay in the initial position
-                // before the new screen rotation.  This is different than the
-                // snapshot transformation because the snapshot is always based
-                // of the native orientation of the screen, not the orientation
-                // we were last in.
-                createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
-
-                final Rect outer;
-                final Rect inner;
-                if (mForceDefaultOrientation) {
-                    // Going from a smaller Display to a larger Display, add curtains to sides
-                    // or top and bottom. Going from a larger to smaller display will result in
-                    // no BlackSurfaces being constructed.
-                    outer = mCurrentDisplayRect;
-                    inner = mOriginalDisplayRect;
-                } else {
-                    outer = new Rect(-mWidth, -mHeight, mWidth * 2, mHeight * 2);
-                    inner = new Rect(0, 0, mWidth, mHeight);
-                }
-                mExitingBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
-                        SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation,
-                        mRotationLayer);
-            } catch (OutOfResourcesException e) {
-                Slog.w(TAG, "Unable to allocate black surface", e);
-            }
+        if (customAnim) {
+            mRotateAlphaAnimation.restrictDuration(maxAnimationDuration);
+            mRotateAlphaAnimation.scaleCurrentDuration(animationScale);
         }
 
         if (customAnim && mEnteringBlackFrame == null) {
@@ -451,7 +398,12 @@
             }
         }
 
-        mSurfaceRotationAnimationController.startAnimation();
+        if (customAnim) {
+            mSurfaceRotationAnimationController.startCustomAnimation();
+        } else {
+            mSurfaceRotationAnimationController.startScreenRotationAnimation();
+        }
+
         return true;
     }
 
@@ -460,11 +412,13 @@
      */
     public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration,
             float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
-        if (mSurfaceControl == null) {
+        if (mScreenshotLayer == null) {
             // Can't do animation.
             return false;
         }
         if (!mStarted) {
+            mEndLuma = RotationAnimationUtils.getLumaOfSurfaceControl(mDisplayContent.getDisplay(),
+                    mDisplayContent.getWindowingLayer());
             startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight,
                     exitAnim, enterAnim);
         }
@@ -480,28 +434,30 @@
             mSurfaceRotationAnimationController.cancel();
             mSurfaceRotationAnimationController = null;
         }
-        if (mSurfaceControl != null) {
-            ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "  FREEZE %s: DESTROY", mSurfaceControl);
-            mSurfaceControl = null;
+
+        if (mScreenshotLayer != null) {
+            ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "  FREEZE %s: DESTROY", mScreenshotLayer);
             SurfaceControl.Transaction t = mService.mTransactionFactory.get();
-            if (mRotationLayer != null) {
-                if (mRotationLayer.isValid()) {
-                    t.remove(mRotationLayer);
-                }
-                mRotationLayer = null;
+            if (mScreenshotLayer.isValid()) {
+                t.remove(mScreenshotLayer);
             }
+            mScreenshotLayer = null;
+
             if (mEnterBlackFrameLayer != null) {
                 if (mEnterBlackFrameLayer.isValid()) {
                     t.remove(mEnterBlackFrameLayer);
                 }
                 mEnterBlackFrameLayer = null;
             }
+            if (mBackColorSurface != null) {
+                if (mBackColorSurface.isValid()) {
+                    t.remove(mBackColorSurface);
+                }
+                mBackColorSurface = null;
+            }
             t.apply();
         }
-        if (mExitingBlackFrame != null) {
-            mExitingBlackFrame.kill();
-            mExitingBlackFrame = null;
-        }
+
         if (mEnteringBlackFrame != null) {
             mEnteringBlackFrame.kill();
             mEnteringBlackFrame = null;
@@ -537,18 +493,28 @@
      * Utility class that runs a {@link ScreenRotationAnimation} on the {@link
      * SurfaceAnimationRunner}.
      * <p>
-     * The rotation animation is divided into the following hierarchy:
+     * The rotation animation supports both screen rotation and custom animations
+     *
+     * For custom animations:
      * <ul>
-     * <li> A first rotation layer, containing the blackframes. This layer is animated by the
-     * "screen_rotate_X_exit" that applies a scale and rotate and where X is value of the rotation.
-     *     <ul>
-     *         <li> A child layer containing the screenshot on which is added an animation of it's
-     *     alpha channel ("screen_rotate_alpha") and that will rotate with his parent layer.</li>
-     *     </ul>
-     * <li> A second rotation layer used when custom animations are passed in
+     *   <li>
+     *     The screenshot layer which has an added animation of it's alpha channel
+     *     ("screen_rotate_alpha") and that will be applied along with the custom animation.
+     *   </li>
+     *   <li> A device layer that is animated with the provided custom animation </li>
+     * </ul>
+     *
+     * For screen rotation:
+     * <ul>
+     *   <li> A rotation layer that is both rotated and faded out during a single animation </li>
+     *   <li> A device layer that is both rotated and faded in during a single animation </li>
+     *   <li> A background color layer that transitions colors behind the first two layers </li>
+     * </ul>
+     *
      * {@link ScreenRotationAnimation#startAnimation(
      *     SurfaceControl.Transaction, long, float, int, int, int, int)}.
      * </ul>
+     *
      * <p>
      * Thus an {@link LocalAnimationAdapter.AnimationSpec} is created for each of
      * this three {@link SurfaceControl}s which then delegates the animation to the
@@ -556,22 +522,35 @@
      */
     class SurfaceRotationAnimationController {
         private SurfaceAnimator mDisplayAnimator;
-        private SurfaceAnimator mEnterBlackFrameAnimator;
         private SurfaceAnimator mScreenshotRotationAnimator;
         private SurfaceAnimator mRotateScreenAnimator;
+        private SurfaceAnimator mEnterBlackFrameAnimator;
+
+        void startCustomAnimation() {
+            try {
+                mService.mSurfaceAnimationRunner.deferStartingAnimations();
+                mRotateScreenAnimator = startScreenshotAlphaAnimation();
+                mDisplayAnimator = startDisplayRotation();
+                if (mEnteringBlackFrame != null) {
+                    mEnterBlackFrameAnimator = startEnterBlackFrameAnimation();
+                }
+            } finally {
+                mService.mSurfaceAnimationRunner.continueStartingAnimations();
+            }
+        }
 
         /**
          * Start the rotation animation of the display and the screenshot on the
          * {@link SurfaceAnimationRunner}.
          */
-        void startAnimation() {
-            mRotateScreenAnimator = startScreenshotAlphaAnimation();
-            mDisplayAnimator = startDisplayRotation();
-            if (mExitingBlackFrame != null) {
+        void startScreenRotationAnimation() {
+            try {
+                mService.mSurfaceAnimationRunner.deferStartingAnimations();
+                mDisplayAnimator = startDisplayRotation();
                 mScreenshotRotationAnimator = startScreenshotRotationAnimation();
-            }
-            if (mEnteringBlackFrame != null) {
-                mEnterBlackFrameAnimator = startEnterBlackFrameAnimation();
+                startColorAnimation();
+            } finally {
+                mService.mSurfaceAnimationRunner.continueStartingAnimations();
             }
         }
 
@@ -596,8 +575,8 @@
 
         private SurfaceAnimator startScreenshotAlphaAnimation() {
             return startAnimation(initializeBuilder()
-                            .setSurfaceControl(mSurfaceControl)
-                            .setAnimationLeashParent(mRotationLayer)
+                            .setSurfaceControl(mScreenshotLayer)
+                            .setAnimationLeashParent(mDisplayContent.getOverlayLayer())
                             .setWidth(mWidth)
                             .setHeight(mHeight)
                             .build(),
@@ -616,13 +595,67 @@
 
         private SurfaceAnimator startScreenshotRotationAnimation() {
             return startAnimation(initializeBuilder()
-                            .setSurfaceControl(mRotationLayer)
+                            .setSurfaceControl(mScreenshotLayer)
                             .setAnimationLeashParent(mDisplayContent.getOverlayLayer())
                             .build(),
                     createWindowAnimationSpec(mRotateExitAnimation),
                     this::onAnimationEnd);
         }
 
+
+        /**
+         * Applies the color change from {@link #mStartLuma} to {@link #mEndLuma} as a
+         * grayscale color
+         */
+        private void startColorAnimation() {
+            int colorTransitionMs = mContext.getResources().getInteger(
+                    R.integer.config_screen_rotation_color_transition);
+            final SurfaceAnimationRunner runner = mService.mSurfaceAnimationRunner;
+            final float[] rgbTmpFloat = new float[3];
+            final int startColor = Color.rgb(mStartLuma, mStartLuma, mStartLuma);
+            final int endColor = Color.rgb(mEndLuma, mEndLuma, mEndLuma);
+            final long duration = colorTransitionMs * (long) mService.getCurrentAnimatorScale();
+            final ArgbEvaluator va = ArgbEvaluator.getInstance();
+            runner.startAnimation(
+                new LocalAnimationAdapter.AnimationSpec() {
+                    @Override
+                    public long getDuration() {
+                        return duration;
+                    }
+
+                    @Override
+                    public void apply(SurfaceControl.Transaction t, SurfaceControl leash,
+                        long currentPlayTime) {
+                        float fraction = (float)currentPlayTime / (float)getDuration();
+                        int color = (Integer) va.evaluate(fraction, startColor, endColor);
+                        Color middleColor = Color.valueOf(color);
+                        rgbTmpFloat[0] = middleColor.red();
+                        rgbTmpFloat[1] = middleColor.green();
+                        rgbTmpFloat[2] = middleColor.blue();
+                        if (leash.isValid()) {
+                            t.setColor(leash, rgbTmpFloat);
+                        }
+                    }
+
+                    @Override
+                    public void dump(PrintWriter pw, String prefix) {
+                        pw.println(prefix + "startLuma=" + mStartLuma
+                                + " endLuma=" + mEndLuma
+                                + " durationMs=" + colorTransitionMs);
+                    }
+
+                    @Override
+                    public void dumpDebugInner(ProtoOutputStream proto) {
+                        final long token = proto.start(ROTATE);
+                        proto.write(START_LUMA, mStartLuma);
+                        proto.write(END_LUMA, mEndLuma);
+                        proto.write(DURATION_MS, colorTransitionMs);
+                        proto.end(token);
+                    }
+                },
+                mBackColorSurface, mDisplayContent.getPendingTransaction(), null);
+        }
+
         private WindowAnimationSpec createWindowAnimationSpec(Animation mAnimation) {
             return new WindowAnimationSpec(mAnimation, new Point(0, 0) /* position */,
                     false /* canSkipFirstFrame */, 0 /* WindowCornerRadius */);
@@ -646,7 +679,6 @@
 
             LocalAnimationAdapter localAnimationAdapter = new LocalAnimationAdapter(
                     animationSpec, mService.mSurfaceAnimationRunner);
-
             animator.startAnimation(mDisplayContent.getPendingTransaction(),
                     localAnimationAdapter, false);
             return animator;
@@ -692,7 +724,6 @@
             if (mEnterBlackFrameAnimator != null) {
                 mEnterBlackFrameAnimator.cancelAnimation();
             }
-
             if (mScreenshotRotationAnimator != null) {
                 mScreenshotRotationAnimator.cancelAnimation();
             }
@@ -704,6 +735,10 @@
             if (mDisplayAnimator != null) {
                 mDisplayAnimator.cancelAnimation();
             }
+
+            if (mBackColorSurface != null) {
+                mService.mSurfaceAnimationRunner.onAnimationCancelled(mBackColorSurface);
+            }
         }
 
         public boolean isAnimating() {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 3b349b8..5babdaf 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -31,6 +31,7 @@
 
 import android.annotation.Nullable;
 import android.content.ClipData;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
@@ -189,7 +190,8 @@
             Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
             Rect outStableInsets, Rect outBackdropFrame,
             DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
-            SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
+            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+            Point outSurfaceSize) {
         if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
@@ -197,7 +199,7 @@
                 requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                 outFrame, outContentInsets, outVisibleInsets,
                 outStableInsets, outBackdropFrame, cutout,
-                mergedConfiguration, outSurfaceControl, outInsetsState);
+                mergedConfiguration, outSurfaceControl, outInsetsState, outSurfaceSize);
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
diff --git a/services/core/java/com/android/server/wm/StatusBarController.java b/services/core/java/com/android/server/wm/StatusBarController.java
index f4260d3..cac992a 100644
--- a/services/core/java/com/android/server/wm/StatusBarController.java
+++ b/services/core/java/com/android/server/wm/StatusBarController.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
-import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
 
 import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
 
@@ -102,11 +101,6 @@
         }
     }
 
-    @Override
-    protected boolean skipAnimation() {
-        return mWin.getAttrs().height == MATCH_PARENT;
-    }
-
     AppTransitionListener getAppTransitionListener() {
         return mAppTransitionListener;
     }
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 50cea2e..5633b6b 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -78,6 +78,10 @@
     @GuardedBy("mLock")
     private boolean mAnimationStartDeferred;
 
+    /**
+     * There should only ever be one instance of this class. Usual spot for it is with
+     * {@link WindowManagerService}
+     */
     SurfaceAnimationRunner(Supplier<Transaction> transactionFactory,
             PowerManagerInternal powerManagerInternal) {
         this(null /* callbackProvider */, null /* animatorFactory */,
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 5286a6e..cb1676f 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -55,7 +55,9 @@
     private final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
     @VisibleForTesting
     @Nullable
-    final Runnable mAnimationFinishedCallback;
+    final Runnable mStaticAnimationFinishedCallback;
+    @Nullable
+    private Runnable mAnimationFinishedCallback;
     private boolean mAnimationStartDelayed;
 
     /**
@@ -66,7 +68,7 @@
             WindowManagerService service) {
         mAnimatable = animatable;
         mService = service;
-        mAnimationFinishedCallback = animationFinishedCallback;
+        mStaticAnimationFinishedCallback = animationFinishedCallback;
         mInnerAnimationFinishedCallback = getFinishedCallback(animationFinishedCallback);
     }
 
@@ -89,10 +91,14 @@
                     if (anim != mAnimation) {
                         return;
                     }
+                    final Runnable animationFinishCallback = mAnimationFinishedCallback;
                     reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
                     if (animationFinishedCallback != null) {
                         animationFinishedCallback.run();
                     }
+                    if (animationFinishCallback != null) {
+                        animationFinishCallback.run();
+                    }
                 };
                 if (!mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)) {
                     resetAndInvokeFinish.run();
@@ -111,10 +117,13 @@
      * @param hidden Whether the container holding the child surfaces is currently visible or not.
      *               This is important as it will start with the leash hidden or visible before
      *               handing it to the component that is responsible to run the animation.
+     * @param animationFinishedCallback The callback being triggered when the animation finishes.
      */
-    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
+    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
+            @Nullable Runnable animationFinishedCallback) {
         cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
         mAnimation = anim;
+        mAnimationFinishedCallback = animationFinishedCallback;
         final SurfaceControl surface = mAnimatable.getSurfaceControl();
         if (surface == null) {
             Slog.w(TAG, "Unable to start animation, surface is null or no children.");
@@ -131,6 +140,10 @@
         mAnimation.startAnimation(mLeash, t, mInnerAnimationFinishedCallback);
     }
 
+    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
+        startAnimation(t, anim, hidden, null /* animationFinishedCallback */);
+    }
+
     /**
      * Begins with delaying all animations to start. Any subsequent call to {@link #startAnimation}
      * will not start the animation until {@link #endDelayingAnimationStart} is called. When an
@@ -232,6 +245,7 @@
         cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
         mLeash = from.mLeash;
         mAnimation = from.mAnimation;
+        mAnimationFinishedCallback = from.mAnimationFinishedCallback;
 
         // Cancel source animation, but don't let animation runner cancel the animation.
         from.cancelAnimation(t, false /* restarting */, false /* forwardCancel */);
@@ -258,13 +272,19 @@
         if (DEBUG_ANIM) Slog.i(TAG, "Cancelling animation restarting=" + restarting);
         final SurfaceControl leash = mLeash;
         final AnimationAdapter animation = mAnimation;
+        final Runnable animationFinishedCallback = mAnimationFinishedCallback;
         reset(t, false);
         if (animation != null) {
             if (!mAnimationStartDelayed && forwardCancel) {
                 animation.onAnimationCancelled(leash);
             }
-            if (!restarting && mAnimationFinishedCallback != null) {
-                mAnimationFinishedCallback.run();
+            if (!restarting) {
+                if (mStaticAnimationFinishedCallback != null) {
+                    mStaticAnimationFinishedCallback.run();
+                }
+                if (animationFinishedCallback != null) {
+                    animationFinishedCallback.run();
+                }
             }
         }
 
@@ -304,6 +324,7 @@
         }
         mLeash = null;
         mAnimation = null;
+        mAnimationFinishedCallback = null;
 
         if (reparent) {
             // Make sure to inform the animatable after the surface was reparented (or reparent
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5cb7091..9e6cb68 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -30,6 +30,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.WindowConfiguration.activityTypeToString;
+import static android.app.WindowConfiguration.windowingModeToString;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
@@ -69,6 +71,7 @@
 import static com.android.server.am.TaskRecordProto.STACK_ID;
 import static com.android.server.am.TaskRecordProto.TASK;
 import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
+import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
@@ -82,6 +85,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskManagerService.TAG_STACK;
 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
 import static com.android.server.wm.TaskProto.APP_WINDOW_TOKENS;
@@ -93,6 +97,7 @@
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
 
@@ -121,7 +126,6 @@
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.IBinder;
-import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -203,9 +207,9 @@
 
     // Current version of the task record we persist. Used to check if we need to run any upgrade
     // code.
-    private static final int PERSIST_TASK_VERSION = 1;
+    static final int PERSIST_TASK_VERSION = 1;
 
-    private static final int INVALID_MIN_SIZE = -1;
+    static final int INVALID_MIN_SIZE = -1;
 
     /**
      * The modes to control how the stack is moved to the front when calling {@link Task#reparent}.
@@ -332,6 +336,8 @@
     final TaskActivitiesReport mReuseActivitiesReport = new TaskActivitiesReport();
 
     final ActivityTaskManagerService mAtmService;
+    final ActivityStackSupervisor mStackSupervisor;
+    final RootWindowContainer mRootWindowContainer;
 
     /* Unique identifier for this task. */
     final int mTaskId;
@@ -346,8 +352,12 @@
     // TODO(b/119687367): This member is temporary.
     private final Rect mOverrideDisplayedBounds = new Rect();
 
+    // Id of the previous display the stack was on.
+    int mPrevDisplayId = INVALID_DISPLAY;
+
     /** ID of the display which rotation {@link #mRotation} has. */
     private int mLastRotationDisplayId = INVALID_DISPLAY;
+
     /**
      * Display rotation as of the last time {@link #setBounds(Rect)} was called or this task was
      * moved to a new display.
@@ -389,8 +399,37 @@
 
     private static Exception sTmpException;
 
+    /** ActivityRecords that are exiting, but still on screen for animations. */
+    final ArrayList<ActivityRecord> mExitingActivities = new ArrayList<>();
+
+    /**
+     * When we are in the process of pausing an activity, before starting the
+     * next one, this variable holds the activity that is currently being paused.
+     */
+    ActivityRecord mPausingActivity = null;
+
+    /**
+     * This is the last activity that we put into the paused state.  This is
+     * used to determine if we need to do an activity transition while sleeping,
+     * when we normally hold the top activity paused.
+     */
+    ActivityRecord mLastPausedActivity = null;
+
+    /**
+     * Activities that specify No History must be removed once the user navigates away from them.
+     * If the device goes to sleep with such an activity in the paused state then we save it here
+     * and finish it later if another activity replaces it on wakeup.
+     */
+    ActivityRecord mLastNoHistoryActivity = null;
+
+    /** Current activity that is resumed, or null if there is none. */
+    ActivityRecord mResumedActivity = null;
+
     private boolean mForceShowForAllUsers;
 
+    /** When set, will force the task to report as invisible. */
+    boolean mForceHidden = false;
+
     private final FindRootHelper mFindRootHelper = new FindRootHelper();
     private class FindRootHelper {
         private ActivityRecord mRoot;
@@ -489,6 +528,8 @@
 
         EventLogTags.writeWmTaskCreated(_taskId, stack != null ? stack.mStackId : INVALID_STACK_ID);
         mAtmService = atmService;
+        mStackSupervisor = atmService.mStackSupervisor;
+        mRootWindowContainer = mAtmService.mRootWindowContainer;
         mTaskId = _taskId;
         mUserId = _userId;
         mResizeMode = resizeMode;
@@ -552,7 +593,7 @@
         if (autoRemoveFromRecents() || isVoiceSession) {
             // Task creator asked to remove this when done, or this task was a voice
             // interaction, so it should not remain on the recent tasks list.
-            mAtmService.mStackSupervisor.mRecentTasks.remove(this);
+            mStackSupervisor.mRecentTasks.remove(this);
         }
 
         removeIfPossible();
@@ -561,13 +602,18 @@
     @VisibleForTesting
     @Override
     void removeIfPossible() {
-        mAtmService.getLockTaskController().clearLockedTask(this);
+        final boolean isRootTask = isRootTask();
+        if (!isRootTask) {
+            mAtmService.getLockTaskController().clearLockedTask(this);
+        }
         if (shouldDeferRemoval()) {
             if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + mTaskId);
             return;
         }
         removeImmediately();
-        mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);
+        if (!isRootTask) {
+            mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);
+        }
     }
 
     void setResizeMode(int resizeMode) {
@@ -575,8 +621,8 @@
             return;
         }
         mResizeMode = resizeMode;
-        mAtmService.mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
-        mAtmService.mRootWindowContainer.resumeFocusedStacksTopActivities();
+        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+        mRootWindowContainer.resumeFocusedStacksTopActivities();
         updateTaskDescription();
     }
 
@@ -593,7 +639,7 @@
                 setBounds(bounds);
                 if (!inFreeformWindowingMode()) {
                     // re-restore the task so it can have the proper stack association.
-                    mAtmService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
+                    mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
                 }
                 return true;
             }
@@ -629,10 +675,9 @@
                     // this won't cause tons of irrelevant windows being preserved because only
                     // activities in this task may experience a bounds change. Configs for other
                     // activities stay the same.
-                    mAtmService.mRootWindowContainer.ensureActivitiesVisible(r, 0,
-                            preserveWindow);
+                    mRootWindowContainer.ensureActivitiesVisible(r, 0, preserveWindow);
                     if (!kept) {
-                        mAtmService.mRootWindowContainer.resumeFocusedStacksTopActivities();
+                        mRootWindowContainer.resumeFocusedStacksTopActivities();
                     }
                 }
             }
@@ -696,8 +741,8 @@
     boolean reparent(ActivityStack preferredStack, int position,
             @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
             boolean schedulePictureInPictureModeChange, String reason) {
-        final ActivityStackSupervisor supervisor = mAtmService.mStackSupervisor;
-        final RootWindowContainer root = mAtmService.mRootWindowContainer;
+        final ActivityStackSupervisor supervisor = mStackSupervisor;
+        final RootWindowContainer root = mRootWindowContainer;
         final WindowManagerService windowManager = mAtmService.mWindowManager;
         final ActivityStack sourceStack = getStack();
         final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
@@ -766,7 +811,7 @@
                         wasPaused, reason);
             }
             if (!animate) {
-                mAtmService.mStackSupervisor.mNoAnimActivities.add(topActivity);
+                mStackSupervisor.mNoAnimActivities.add(topActivity);
             }
 
             // We might trigger a configuration change. Save the current task bounds for freezing.
@@ -785,7 +830,7 @@
             } else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
                 Rect bounds = getLaunchBounds();
                 if (bounds == null) {
-                    mAtmService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
+                    mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
                     bounds = configBounds;
                 }
                 kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
@@ -793,7 +838,7 @@
                 if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
                     // Move recents to front so it is not behind home stack when going into docked
                     // mode
-                    mAtmService.mStackSupervisor.moveRecentsStackToFront(reason);
+                    mStackSupervisor.moveRecentsStackToFront(reason);
                 }
                 kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
                         !mightReplaceWindow, deferResume);
@@ -859,6 +904,14 @@
         mCallingPackage = r.launchedFromPackage;
         setIntent(r.intent, r.info);
         setLockTaskAuth(r);
+
+        final WindowContainer parent = getParent();
+        if (parent != null) {
+            final Task t = parent.asTask();
+            if (t != null) {
+                t.setIntent(r);
+            }
+        }
     }
 
     /** Sets the original intent, _without_ updating the calling uid or package. */
@@ -972,8 +1025,13 @@
     }
 
     boolean returnsToHomeStack() {
-        final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
-        return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
+        if (inMultiWindowMode() || !hasChild()) return false;
+        if (intent != null) {
+            final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
+            return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
+        }
+        final Task bottomTask = getBottomMostTask();
+        return bottomTask != this && bottomTask.returnsToHomeStack();
     }
 
     void setPrevAffiliate(Task prevAffiliate) {
@@ -988,37 +1046,72 @@
 
     @Override
     void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
-        final ActivityStack oldStack = ((ActivityStack) oldParent);
-        final ActivityStack newStack = ((ActivityStack) newParent);
+        final DisplayContent display = newParent != null
+                ? ((WindowContainer) newParent).getDisplayContent() : null;
+        final DisplayContent oldDisplay = oldParent != null
+                ? ((WindowContainer) oldParent).getDisplayContent() : null;
+
+        mPrevDisplayId = (oldDisplay != null) ? oldDisplay.mDisplayId : INVALID_DISPLAY;
 
         // Task is going to be removed, clean it up before detaching from hierarchy.
         if (oldParent != null && newParent == null) {
             cleanUpResourcesForDestroy();
         }
 
+        if (display != null) {
+            // TODO(NOW!): Chat with the erosky@ of this code to see if this really makes sense here...
+            // Rotations are relative to the display. This means if there are 2 displays rotated
+            // differently (eg. 2 monitors with one landscape and one portrait), moving a stack
+            // from one to the other could look like a rotation change. To prevent this
+            // apparent rotation change (and corresponding bounds rotation), pretend like our
+            // current rotation is already the same as the new display.
+            // Note, if ActivityStack or related logic ever gets nested, this logic will need
+            // to move to onConfigurationChanged.
+            getConfiguration().windowConfiguration.setRotation(
+                    display.getWindowConfiguration().getRotation());
+        }
+
         super.onParentChanged(newParent, oldParent);
 
-        if (oldStack != null) {
-            final PooledConsumer c = PooledLambda.obtainConsumer(
-                    ActivityStack::onActivityRemovedFromStack, oldStack,
-                    PooledLambda.__(ActivityRecord.class));
-            forAllActivities(c);
-            c.recycle();
+        // TODO(NOW): The check for null display content and setting it to null doesn't really
+        //  make sense here...
 
-            if (oldStack.inPinnedWindowingMode()
-                    && (newStack == null || !newStack.inPinnedWindowingMode())) {
+        // TODO(stack-merge): This is mostly taking care of the case where the stask is removing from
+        // the display, so we should probably consolidate it there instead.
+
+        if (getParent() == null && mDisplayContent != null) {
+            EventLogTags.writeWmStackRemoved(getStackId());
+            mDisplayContent = null;
+            mWmService.mWindowPlacerLocked.requestTraversal();
+        }
+
+        if (oldParent != null) {
+            final Task oldParentTask = ((WindowContainer) oldParent).asTask();
+            if (oldParentTask != null) {
+                final PooledConsumer c = PooledLambda.obtainConsumer(
+                        Task::cleanUpActivityReferences, oldParentTask,
+                        PooledLambda.__(ActivityRecord.class));
+                forAllActivities(c);
+                c.recycle();
+            }
+
+            if (oldParent.inPinnedWindowingMode()
+                    && (newParent == null || !newParent.inPinnedWindowingMode())) {
                 // Notify if a task from the pinned stack is being removed
                 // (or moved depending on the mode).
                 mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned();
             }
         }
 
-        if (newStack != null) {
-            final PooledConsumer c = PooledLambda.obtainConsumer(
-                    ActivityStack::onActivityAddedToStack, newStack,
-                    PooledLambda.__(ActivityRecord.class));
-            forAllActivities(c);
-            c.recycle();
+        if (newParent != null) {
+            final Task newParentTask = ((WindowContainer) newParent).asTask();
+            if (newParentTask != null) {
+                final ActivityRecord top = newParentTask.getTopNonFinishingActivity(
+                        false /* includeOverlays */);
+                if (top != null && top.isState(RESUMED)) {
+                    newParentTask.setResumedActivity(top, "addedToTask");
+                }
+            }
 
             // TODO: Ensure that this is actually necessary here
             // Notify the voice session if required
@@ -1049,7 +1142,41 @@
             forceWindowsScaleable(false /* force */);
         }
 
-        mAtmService.mRootWindowContainer.updateUIDsPresentOnDisplay();
+        mRootWindowContainer.updateUIDsPresentOnDisplay();
+    }
+
+    void cleanUpActivityReferences(ActivityRecord r) {
+        final WindowContainer parent = getParent();
+        if (parent != null && parent.asTask() != null) {
+            parent.asTask().cleanUpActivityReferences(r);
+            return;
+        }
+        r.removeTimeouts();
+        mExitingActivities.remove(r);
+
+        if (mResumedActivity != null && mResumedActivity == r) {
+            setResumedActivity(null, "cleanUpActivityReferences");
+        }
+        if (mPausingActivity != null && mPausingActivity == r) {
+            mPausingActivity = null;
+        }
+    }
+
+    /** @return the currently resumed activity. */
+    ActivityRecord getResumedActivity() {
+        return mResumedActivity;
+    }
+
+    void setResumedActivity(ActivityRecord r, String reason) {
+        if (mResumedActivity == r) {
+            return;
+        }
+
+        if (ActivityTaskManagerDebugConfig.DEBUG_STACK) Slog.d(TAG_STACK,
+                "setResumedActivity stack:" + this + " + from: "
+                + mResumedActivity + " to:" + r + " reason:" + reason);
+        mResumedActivity = r;
+        mStackSupervisor.updateTopResumedActivityIfNeeded();
     }
 
     void updateTaskMovement(boolean toFront) {
@@ -1062,7 +1189,7 @@
                 mLastTimeMoved *= -1;
             }
         }
-        mAtmService.mRootWindowContainer.invalidateTaskLayers();
+        mRootWindowContainer.invalidateTaskLayers();
     }
 
     // Close up recents linked list.
@@ -1115,7 +1242,11 @@
 
     /** Returns the intent for the root activity for this task */
     Intent getBaseIntent() {
-        return intent != null ? intent : affinityIntent;
+        if (intent != null) return intent;
+        if (affinityIntent != null) return affinityIntent;
+        // Probably a task that contains other tasks, so return the intent for the top task?
+        final Task topTask = getTopMostTask();
+        return topTask != null ? topTask.getBaseIntent() : null;
     }
 
     /** Returns the first non-finishing activity from the bottom. */
@@ -1200,11 +1331,18 @@
         // If this task had any child before we added this one.
         boolean hadChild = hasChild();
 
-        final ActivityRecord r = (ActivityRecord) child;
-        index = getAdjustedAddPosition(r, index);
-        super.addChild(r, index);
+        index = getAdjustedChildPosition(child, index);
+        super.addChild(child, index);
 
         ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);
+
+        // Make sure the list of display UID whitelists is updated
+        // now that this record is in a new task.
+        mRootWindowContainer.updateUIDsPresentOnDisplay();
+
+        final ActivityRecord r = child.asActivityRecord();
+        if (r == null) return;
+
         r.inHistory = true;
 
         // Only set this based on the first activity
@@ -1229,10 +1367,6 @@
         }
 
         updateEffectiveIntent();
-
-        // Make sure the list of display UID whitelists is updated
-        // now that this record is in a new task.
-        mAtmService.mRootWindowContainer.updateUIDsPresentOnDisplay();
     }
 
     void addChild(ActivityRecord r) {
@@ -1240,12 +1374,19 @@
     }
 
     @Override
-    void removeChild(WindowContainer r) {
+    void removeChild(WindowContainer child) {
+        removeChild(child, "removeChild");
+    }
+
+    void removeChild(WindowContainer r, String reason) {
         if (!mChildren.contains(r)) {
             Slog.e(TAG, "removeChild: r=" + r + " not found in t=" + this);
             return;
         }
 
+        if (DEBUG_TASK_MOVEMENT) {
+            Slog.d(TAG_WM, "removeChild: child=" + r + " reason=" + reason);
+        }
         super.removeChild(r);
 
         if (inPinnedWindowingMode()) {
@@ -1255,7 +1396,15 @@
             mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
         }
 
-        final String reason = "removeChild";
+        final boolean isRootTask = isRootTask();
+        if (isRootTask) {
+            final DisplayContent display = getDisplayContent();
+            if (display.isSingleTaskInstance()) {
+                mAtmService.notifySingleTaskDisplayEmpty(display.mDisplayId);
+            }
+            display.mDisplayContent.setLayoutNeeded();
+        }
+
         if (hasChild()) {
             updateEffectiveIntent();
 
@@ -1270,12 +1419,14 @@
                 // work.
                 // TODO: If the callers to removeChild() changes such that we have multiple places
                 //       where we are destroying the task, move this back into removeChild()
-                mAtmService.mStackSupervisor.removeTask(this, false /* killProcess */,
+                mStackSupervisor.removeTask(this, false /* killProcess */,
                         !REMOVE_FROM_RECENTS, reason);
             }
         } else if (!mReuseTask) {
             // Remove entire task if it doesn't have any activity left and it isn't marked for reuse
-            getStack().removeChild(this, reason);
+            if (!isRootTask) {
+                getStack().removeChild(this, reason);
+            }
             EventLogTags.writeWmTaskRemoved(mTaskId,
                     "removeChild: last r=" + r + " in t=" + this);
             removeIfPossible();
@@ -1446,11 +1597,15 @@
 
     @Override
     public boolean supportsSplitScreenWindowingMode() {
+        final Task topTask = getTopMostTask();
+        return super.supportsSplitScreenWindowingMode()
+                && (topTask == null || topTask.supportsSplitScreenWindowingModeInner());
+    }
+
+    private boolean supportsSplitScreenWindowingModeInner() {
         // A task can not be docked even if it is considered resizeable because it only supports
         // picture-in-picture mode but has a non-resizeable resizeMode
         return super.supportsSplitScreenWindowingMode()
-                // TODO(task-group): Probably makes sense to move this and associated code into
-                // WindowContainer so it affects every node.
                 && mAtmService.mSupportsSplitScreenMultiWindow
                 && (mAtmService.mForceResizableActivities
                         || (isResizeable(false /* checkSupportsPip */)
@@ -1465,7 +1620,7 @@
      *         secondary display.
      */
     boolean canBeLaunchedOnDisplay(int displayId) {
-        return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
+        return mStackSupervisor.canPlaceEntityOnDisplay(displayId,
                 -1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
     }
 
@@ -1535,6 +1690,14 @@
         }
         mAtmService.getTaskChangeNotificationController().notifyTaskDescriptionChanged(
                 getTaskInfo());
+
+        final WindowContainer parent = getParent();
+        if (parent != null) {
+            final Task t = parent.asTask();
+            if (t != null) {
+                t.updateTaskDescription();
+            }
+        }
     }
 
     private static boolean setTaskDescriptionFromActivityAboveRoot(
@@ -1577,9 +1740,11 @@
     @VisibleForTesting
     void updateEffectiveIntent() {
         final ActivityRecord root = getRootActivity(true /*setToBottomIfNone*/);
-        setIntent(root);
-        // Update the task description when the activities change
-        updateTaskDescription();
+        if (root != null) {
+            setIntent(root);
+            // Update the task description when the activities change
+            updateTaskDescription();
+        }
     }
 
     void adjustForMinimalTaskDimensions(Rect bounds, Rect previousBounds) {
@@ -1593,9 +1758,8 @@
         // If the task has no requested minimal size, we'd like to enforce a minimal size
         // so that the user can not render the task too small to manipulate. We don't need
         // to do this for the pinned stack as the bounds are controlled by the system.
-        if (!inPinnedWindowingMode() && getDisplayContent() != null) {
-            final int defaultMinSizeDp =
-                    mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp;
+        if (!inPinnedWindowingMode() && getStack() != null) {
+            final int defaultMinSizeDp = mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp;
             final DisplayContent display = getDisplayContent();
             final float density =
                     (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
@@ -1659,10 +1823,25 @@
      * @param reason The reason for the change.
      */
     void onActivityStateChanged(ActivityRecord record, ActivityState state, String reason) {
-        final ActivityStack parent = getStack();
+        final Task parentTask = getParent().asTask();
+        if (parentTask != null) {
+            parentTask.onActivityStateChanged(record, state, reason);
+            return;
+        }
 
-        if (parent != null) {
-            parent.onActivityStateChanged(record, state, reason);
+        if (record == mResumedActivity && state != RESUMED) {
+            setResumedActivity(null, reason + " - onActivityStateChanged");
+        }
+
+        if (state == RESUMED) {
+            if (ActivityTaskManagerDebugConfig.DEBUG_STACK) {
+                Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:" + reason);
+            }
+            setResumedActivity(record, reason + " - onActivityStateChanged");
+            if (record == mRootWindowContainer.getTopResumedActivity()) {
+                mAtmService.setResumedActivityUncheckLocked(record, reason);
+            }
+            mStackSupervisor.mRecentTasks.add(record.getTask());
         }
     }
 
@@ -1684,7 +1863,7 @@
         final boolean wasInMultiWindowMode = inMultiWindowMode();
         super.onConfigurationChanged(newParentConfig);
         if (wasInMultiWindowMode != inMultiWindowMode()) {
-            mAtmService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
+            mStackSupervisor.scheduleUpdateMultiWindowMode(this);
         }
 
         // If the configuration supports persistent bounds (eg. Freeform), keep track of the
@@ -1725,7 +1904,7 @@
         }
 
         // Saves the new state so that we can launch the activity at the same location.
-        mAtmService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
+        mStackSupervisor.mLaunchParamsPersister.saveTask(this);
     }
 
     /**
@@ -1987,6 +2166,10 @@
 
     @Override
     void resolveOverrideConfiguration(Configuration newParentConfig) {
+        if (isRootTask()) {
+            super.resolveOverrideConfiguration(newParentConfig);
+            return;
+        }
         mTmpBounds.set(getResolvedOverrideConfiguration().windowConfiguration.getBounds());
         super.resolveOverrideConfiguration(newParentConfig);
         int windowingMode =
@@ -2011,12 +2194,12 @@
             final Rect parentBounds =
                     new Rect(newParentConfig.windowConfiguration.getBounds());
             final DisplayContent display = getDisplayContent();
-            if (display != null && display.mDisplayContent != null) {
+            if (display != null) {
                 // If a freeform window moves below system bar, there is no way to move it again
                 // by touch. Because its caption is covered by system bar. So we exclude them
                 // from stack bounds. and then caption will be shown inside stable area.
                 final Rect stableBounds = new Rect();
-                display.mDisplayContent.getStableRect(stableBounds);
+                display.getStableRect(stableBounds);
                 parentBounds.intersect(stableBounds);
             }
 
@@ -2091,6 +2274,7 @@
      * input stack. */
     void updateOverrideConfigurationForStack(ActivityStack inStack) {
         final ActivityStack stack = getStack();
+
         if (stack != null && stack == inStack) {
             return;
         }
@@ -2106,7 +2290,7 @@
             if (mLastNonFullscreenBounds != null) {
                 setBounds(mLastNonFullscreenBounds);
             } else {
-                mAtmService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
+                mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
             }
         } else {
             setBounds(inStack.getRequestedOverrideBounds());
@@ -2149,7 +2333,10 @@
 
     @Override
     DisplayContent getDisplayContent() {
-        return getStack() != null ? getStack().getDisplayContent() : null;
+        // TODO: Why aren't we just using our own display content vs. parent's???
+        final ActivityStack stack = getStack();
+        return stack != null && stack != this
+                ? stack.getDisplayContent() : super.getDisplayContent();
     }
 
     int getDisplayId() {
@@ -2158,7 +2345,8 @@
     }
 
     ActivityStack getStack() {
-        return (ActivityStack) getParent();
+        final WindowContainer parent = getParent();
+        return (ActivityStack) (parent instanceof ActivityStack ? parent : this);
     }
 
     /**
@@ -2169,27 +2357,99 @@
         return stack != null ? stack.mStackId : INVALID_STACK_ID;
     }
 
-    // TODO(task-hierarchy): Needs to take a generic WindowManager when task contains other tasks.
-    int getAdjustedAddPosition(ActivityRecord r, int suggestedPosition) {
-        int maxPosition = mChildren.size();
-        if (!r.isTaskOverlay()) {
-            // We want to place all non-overlay activities below overlays.
-            final ActivityRecord bottomMostOverlay = getActivity((ar) -> ar.isTaskOverlay(), false);
-            if (bottomMostOverlay != null) {
-                maxPosition = Math.max(mChildren.indexOf(bottomMostOverlay) - 1, 0);
+    int getDescendantTaskCount() {
+        final int[] currentCount = {0};
+        final PooledConsumer c = PooledLambda.obtainConsumer((t, count) -> { count[0]++; },
+                PooledLambda.__(Task.class), currentCount);
+        forAllTasks(c, false /* traverseTopToBottom */, this);
+        c.recycle();
+        return currentCount[0];
+    }
+
+    /** Calculate the minimum possible position for a task that can be shown to the user.
+     *  The minimum position will be above all other tasks that can't be shown.
+     *  @param minPosition The minimum position the caller is suggesting.
+     *                  We will start adjusting up from here.
+     *  @param size The size of the current task list.
+     */
+    // TODO: Move user to their own window container.
+    private int computeMinUserPosition(int minPosition, int size) {
+        while (minPosition < size) {
+            final WindowContainer child = mChildren.get(minPosition);
+            final boolean canShow = child.showToCurrentUser();
+            if (canShow) {
+                break;
+            }
+            minPosition++;
+        }
+        return minPosition;
+    }
+
+    /** Calculate the maximum possible position for a task that can't be shown to the user.
+     *  The maximum position will be below all other tasks that can be shown.
+     *  @param maxPosition The maximum position the caller is suggesting.
+     *                  We will start adjusting down from here.
+     */
+    // TODO: Move user to their own window container.
+    private int computeMaxUserPosition(int maxPosition) {
+        while (maxPosition > 0) {
+            final WindowContainer child = mChildren.get(maxPosition);
+            final boolean canShow = child.showToCurrentUser();
+            if (!canShow) {
+                break;
+            }
+            maxPosition--;
+        }
+        return maxPosition;
+    }
+
+    private int getAdjustedChildPosition(WindowContainer wc, int suggestedPosition) {
+        final boolean canShowChild = wc.showToCurrentUser();
+
+        final int size = mChildren.size();
+
+        // Figure-out min/max possible position depending on if child can show for current user.
+        int minPosition = (canShowChild) ? computeMinUserPosition(0, size) : 0;
+        int maxPosition = (canShowChild) ? size : computeMaxUserPosition(size - 1);
+
+        // Factor in always-on-top children in max possible position.
+        if (!wc.isAlwaysOnTop()) {
+
+            // We want to place all non-always-on-top containers below always-on-top ones.
+            while (maxPosition > minPosition) {
+                if (!mChildren.get(maxPosition - 1).isAlwaysOnTop()) break;
+                --maxPosition;
             }
         }
 
-        return Math.min(maxPosition, suggestedPosition);
+        // preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.
+        if (suggestedPosition == POSITION_BOTTOM && minPosition == 0) {
+            return POSITION_BOTTOM;
+        } else if (suggestedPosition == POSITION_TOP && maxPosition == (size - 1)) {
+            return POSITION_TOP;
+        }
+        // Reset position based on minimum/maximum possible positions.
+        return Math.min(Math.max(suggestedPosition, minPosition), maxPosition);
     }
 
     @Override
     void positionChildAt(int position, WindowContainer child, boolean includingParents) {
-        position = getAdjustedAddPosition((ActivityRecord) child, position);
+        position = getAdjustedChildPosition(child, position);
         super.positionChildAt(position, child, includingParents);
+
+        // Log positioning.
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "positionChildAt: child=" + child
+                + " position=" + position + " parent=" + this);
+
+        final int toTop = position >= (mChildren.size() - 1) ? 1 : 0;
+        final Task task = child.asTask();
+        if (task != null) {
+            EventLogTags.writeWmTaskMoved(task.mTaskId, toTop, position);
+        }
     }
 
-    private boolean hasWindowsAlive() {
+    @VisibleForTesting
+    boolean hasWindowsAlive() {
         return getActivity(ActivityRecord::hasWindowsAlive) != null;
     }
 
@@ -2219,8 +2479,6 @@
                 + " from stack=" + getStack());
         EventLogTags.writeWmTaskRemoved(mTaskId, "reParentTask:" + reason);
 
-        position = stack.findPositionForTask(this, position);
-
         reparent(stack, position);
 
         stack.positionChildAt(position, this, moveParents);
@@ -2286,11 +2544,16 @@
 
     @Override
     void onDisplayChanged(DisplayContent dc) {
-        adjustBoundsForDisplayChangeIfNeeded(dc);
+        final boolean isRootTask = isRootTask();
+        if (!isRootTask) {
+            adjustBoundsForDisplayChangeIfNeeded(dc);
+        }
         super.onDisplayChanged(dc);
-        final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY;
-        mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged(
-                mTaskId, displayId);
+        if (!isRootTask) {
+            final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY;
+            mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged(
+                    mTaskId, displayId);
+        }
     }
 
     /**
@@ -2432,7 +2695,7 @@
     }
 
     /** Bounds of the task to be used for dimming, as well as touch related tests. */
-    public void getDimBounds(Rect out) {
+    void getDimBounds(Rect out) {
         final DisplayContent displayContent = getStack().getDisplayContent();
         // It doesn't matter if we in particular are part of the resize, since we couldn't have
         // a DimLayer anyway if we weren't visible.
@@ -2565,6 +2828,11 @@
         mForceShowForAllUsers = forceShowForAllUsers;
     }
 
+    public boolean isAttached() {
+        final DisplayContent display = getDisplayContent();
+        return display != null && !display.isRemoved();
+    }
+
     /**
      * When we are in a floating stack (Freeform, Pinned, ...) we calculate
      * insets differently. However if we are animating to the fullscreen stack
@@ -2576,6 +2844,45 @@
                 && !getStack().isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
     }
 
+    /**
+     * Returns true if the stack is translucent and can have other contents visible behind it if
+     * needed. A stack is considered translucent if it don't contain a visible or
+     * starting (about to be visible) activity that is fullscreen (opaque).
+     * @param starting The currently starting activity or null if there is none.
+     */
+    @VisibleForTesting
+    boolean isTranslucent(ActivityRecord starting) {
+        if (!isAttached() || mForceHidden) {
+            return true;
+        }
+        final PooledPredicate p = PooledLambda.obtainPredicate(Task::isOpaqueActivity,
+                PooledLambda.__(ActivityRecord.class), starting);
+        final ActivityRecord opaque = getActivity(p);
+        p.recycle();
+        return opaque == null;
+    }
+
+    private static boolean isOpaqueActivity(ActivityRecord r, ActivityRecord starting) {
+        if (r.finishing) {
+            // We don't factor in finishing activities when determining translucency since
+            // they will be gone soon.
+            return false;
+        }
+
+        if (!r.visibleIgnoringKeyguard && r != starting) {
+            // Also ignore invisible activities that are not the currently starting
+            // activity (about to be visible).
+            return false;
+        }
+
+        if (r.occludesParent() || r.hasWallpaper) {
+            // Stack isn't translucent if it has at least one fullscreen activity
+            // that is visible.
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public SurfaceControl getAnimationLeashParent() {
         if (WindowManagerService.sHierarchicalAnimations) {
@@ -2616,18 +2923,6 @@
     }
 
     @Override
-    protected void onAnimationFinished() {
-        super.onAnimationFinished();
-        // TODO(b/142617871): we may need to add animation type parameter on onAnimationFinished to
-        //  identify if the callback is for launch animation finish and then calling
-        //  activity#onAnimationFinished.
-        final ActivityRecord activity = getTopMostActivity();
-        if (activity != null) {
-            activity.onAnimationFinished();
-        }
-    }
-
-    @Override
     SurfaceControl.Builder makeSurface() {
         return super.makeSurface().setMetadata(METADATA_TASK_ID, mTaskId);
     }
@@ -2639,7 +2934,7 @@
                 return true;
             }
         }
-        return false;
+        return forAllTasks((t) -> { return t != this && t.isTaskAnimating(); });
     }
 
     /**
@@ -2715,26 +3010,45 @@
         return mTaskDescription;
     }
 
+    // TODO(task-merge): Figure out what's the right thing to do for places that used it.
+    boolean isRootTask() {
+        return getParent() == null || getParent().asTask() == null;
+    }
+
     @Override
     boolean fillsParent() {
-        return matchParentBounds() || !getWindowConfiguration().canResizeTask();
+        return matchParentBounds();
+    }
+
+    void forAllTasks(Consumer<Task> callback, boolean traverseTopToBottom, Task excludedTask) {
+        if (traverseTopToBottom) {
+            super.forAllTasks(callback, traverseTopToBottom);
+            if (excludedTask != this) {
+                callback.accept(this);
+            }
+        } else {
+            super.forAllTasks(callback, traverseTopToBottom);
+            if (excludedTask != this) {
+                callback.accept(this);
+            }
+        }
     }
 
     @Override
     void forAllTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
-        // TODO(task-hierarchy): Change to traverse children when tasks can contain other tasks.
-        callback.accept(this);
+        forAllTasks(callback, traverseTopToBottom, null /* excludedTask */);
     }
 
     @Override
     boolean forAllTasks(Function<Task, Boolean> callback) {
+        if (super.forAllTasks(callback)) return true;
         return callback.apply(this);
     }
 
     @Override
     Task getTask(Predicate<Task> callback, boolean traverseTopToBottom) {
-        // I'm a task!
-        // TODO(task-hierarchy): Change to traverse children when tasks can contain other tasks.
+        final Task t = super.getTask(callback, traverseTopToBottom);
+        if (t != null) return t;
         return callback.test(this) ? this : null;
     }
 
@@ -2770,6 +3084,16 @@
         return mDimmer;
     }
 
+    void dim(float alpha) {
+        mDimmer.dimAbove(getPendingTransaction(), alpha);
+        scheduleAnimation();
+    }
+
+    void stopDimming() {
+        mDimmer.stopDim(getPendingTransaction());
+        scheduleAnimation();
+    }
+
     boolean isTaskForUser(int userId) {
         return mUserId == userId;
     }
@@ -2817,7 +3141,7 @@
     }
 
     @Override
-    public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
         super.dump(pw, prefix, dumpAll);
         final String doublePrefix = prefix + "  ";
 
@@ -2877,6 +3201,17 @@
         return mTaskId == taskId;
     }
 
+    @Override
+    Task asTask() {
+        // I'm a task!
+        return this;
+    }
+
+    // TODO(task-merge): Figure-out how this should work with hierarchy tasks.
+    boolean shouldBeVisible(ActivityRecord starting) {
+        return true;
+    }
+
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("userId="); pw.print(mUserId);
         pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
@@ -2963,7 +3298,7 @@
         if (mRootProcess != null) {
             pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
         }
-        pw.print(prefix); pw.print("stackId="); pw.println(getStackId());
+        pw.print(prefix); pw.print("taskId=" + mTaskId); pw.println(" stackId=" + getStackId());
         pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
         pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
         pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
@@ -2990,6 +3325,10 @@
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         sb.append(" #");
         sb.append(mTaskId);
+        sb.append(" visible=" + shouldBeVisible(null /* starting */));
+        sb.append(" type=" + activityTypeToString(getActivityType()));
+        sb.append(" mode=" + windowingModeToString(getWindowingMode()));
+        sb.append(" translucent=" + isTranslucent(null /* starting */));
         if (affinity != null) {
             sb.append(" A=");
             sb.append(affinity);
@@ -3006,8 +3345,7 @@
         return toString();
     }
 
-    @Override
-    public void dumpDebug(ProtoOutputStream proto, long fieldId,
+    void dumpDebugInner(ProtoOutputStream proto, long fieldId,
             @WindowTraceLogLevel int logLevel) {
         if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
             return;
@@ -3218,13 +3556,13 @@
         Task create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
                 Intent intent, IVoiceInteractionSession voiceSession,
                 IVoiceInteractor voiceInteractor, ActivityStack stack) {
-            return new Task(service, taskId, info, intent, voiceSession, voiceInteractor,
+            return new ActivityStack(service, taskId, info, intent, voiceSession, voiceInteractor,
                     null /*taskDescription*/, stack);
         }
 
         Task create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
                 Intent intent, TaskDescription taskDescription, ActivityStack stack) {
-            return new Task(service, taskId, info, intent, null /*voiceSession*/,
+            return new ActivityStack(service, taskId, info, intent, null /*voiceSession*/,
                     null /*voiceInteractor*/, taskDescription, stack);
         }
 
@@ -3241,7 +3579,7 @@
                 int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
                 int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
                 boolean userSetupComplete, int minWidth, int minHeight, ActivityStack stack) {
-            return new Task(service, taskId, intent, affinityIntent, affinity,
+            return new ActivityStack(service, taskId, intent, affinityIntent, affinity,
                     rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
                     askedCompatMode, userId, effectiveUid, lastDescription,
                     lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
@@ -3483,7 +3821,9 @@
     }
 
     boolean isControlledByTaskOrganizer() {
-        return mTaskOrganizer != null;
+        // TODO(b/147849315): Clean-up relationship between task-org and task-hierarchy. Ideally
+        //  we only give control of the root task.
+        return getTopMostTask().mTaskOrganizer != null;
     }
 
     @Override
@@ -3559,13 +3899,16 @@
     public void setWindowingMode(int windowingMode) {
         super.setWindowingMode(windowingMode);
         windowingMode = getWindowingMode();
-        /*
-         * Different windowing modes may be managed by different task organizers. If
-         * getTaskOrganizer returns null, we still call transferToTaskOrganizer to
-         * make sure we clear it.
-         */
-        final ITaskOrganizer org =
-            mAtmService.mTaskOrganizerController.getTaskOrganizer(windowingMode);
-        setTaskOrganizer(org);
+
+        // TODO(b/147849315): Clean-up relationship between task-org and task-hierarchy. Ideally
+        //  we only give control of the root task.
+        // Different windowing modes may be managed by different task organizers. If
+        // getTaskOrganizer returns null, we still call transferToTaskOrganizer to make sure we
+        // clear it.
+        if (!isRootTask()) {
+            final ITaskOrganizer org =
+                    mAtmService.mTaskOrganizerController.getTaskOrganizer(windowingMode);
+            setTaskOrganizer(org);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index e2a21a9..57de753 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -55,6 +55,7 @@
 import android.graphics.Color;
 import android.graphics.GraphicBuffer;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
@@ -115,6 +116,7 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM;
     private static final int MSG_REPORT_DRAW = 0;
     private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s";
+    private static final Point sSurfaceSize = new Point(); //tmp var for unused relayout param
     private final Window mWindow;
     private final Surface mSurface;
     private SurfaceControl mSurfaceControl;
@@ -227,7 +229,8 @@
         try {
             session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1,
                     tmpFrame, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect,
-                    tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState);
+                    tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
+                    sSurfaceSize);
         } catch (RemoteException e) {
             // Local call.
         }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 3b2d519..1c876d9 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -562,6 +562,13 @@
         return false;
     }
 
+    /** @return true if this window container is a descendant of the input container. */
+    boolean isDescendantOf(WindowContainer ancestor) {
+        final WindowContainer parent = getParent();
+        if (parent == ancestor) return true;
+        return (parent != null) && parent.isDescendantOf(ancestor);
+    }
+
     /**
      * Move a child from it's current place in siblings list to the specified position,
      * with an option to move all its parents to top.
@@ -1832,13 +1839,19 @@
      * @param anim The animation to run.
      * @param hidden Whether our container is currently hidden. TODO This should use isVisible at
      *               some point but the meaning is too weird to work for all containers.
+     * @param animationFinishedCallback The callback being triggered when the animation finishes.
      */
-    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
+    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
+            @Nullable Runnable animationFinishedCallback) {
         if (DEBUG_ANIM) Slog.v(TAG, "Starting animation on " + this + ": " + anim);
 
         // TODO: This should use isVisible() but because isVisible has a really weird meaning at
         // the moment this doesn't work for all animatable window containers.
-        mSurfaceAnimator.startAnimation(t, anim, hidden);
+        mSurfaceAnimator.startAnimation(t, anim, hidden, animationFinishedCallback);
+    }
+
+    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
+        startAnimation(t, anim, hidden, null /* animationFinishedCallback */);
     }
 
     void transferAnimation(WindowContainer from) {
@@ -1891,7 +1904,7 @@
      * @see #getAnimationAdapter
      */
     boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
-                           boolean isVoiceInteraction) {
+            boolean isVoiceInteraction, @Nullable Runnable animationFinishedCallback) {
         if (mWmService.mDisableTransitionAnimation) {
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
                     "applyAnimation: transition animation is disabled or skipped. "
@@ -1911,7 +1924,8 @@
                 AnimationAdapter adapter = adapters.first;
                 AnimationAdapter thumbnailAdapter = adapters.second;
                 if (adapter != null) {
-                    startAnimation(getPendingTransaction(), adapter, !isVisible());
+                    startAnimation(getPendingTransaction(), adapter, !isVisible(),
+                            animationFinishedCallback);
                     if (adapter.getShowWallpaper()) {
                         getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                     }
@@ -2235,4 +2249,14 @@
     void setSurfaceControl(SurfaceControl sc) {
         mSurfaceControl = sc;
     }
+
+    /** Cheap way of doing cast and instanceof. */
+    Task asTask() {
+        return null;
+    }
+
+    /** Cheap way of doing cast and instanceof. */
+    ActivityRecord asActivityRecord() {
+        return null;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index 8e070f1..8948f6f 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -85,7 +85,8 @@
             // We can't use a delegating constructor since we need to
             // reference this::onAnimationFinished
             mSurfaceAnimator =
-                new SurfaceAnimator(this, this::onAnimationFinished, container.mWmService);
+                new SurfaceAnimator(this, null /* animationFinishedCallback */,
+                        container.mWmService);
         }
         mWidth = thumbnailHeader.getWidth();
         mHeight = thumbnailHeader.getHeight();
@@ -139,9 +140,6 @@
         mSurfaceAnimator.startAnimation(t, anim, hidden);
     }
 
-    private void onAnimationFinished() {
-    }
-
     void setShowing(Transaction pendingTransaction, boolean show) {
         // TODO: Not needed anymore once thumbnail is attached to the app.
         if (show) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e3b593e9..cd5da08 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -63,6 +63,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -1283,6 +1284,7 @@
     static boolean excludeWindowTypeFromTapOutTask(int windowType) {
         switch (windowType) {
             case TYPE_STATUS_BAR:
+            case TYPE_NOTIFICATION_SHADE:
             case TYPE_NAVIGATION_BAR:
             case TYPE_INPUT_METHOD_DIALOG:
                 return true;
@@ -2037,7 +2039,8 @@
             long frameNumber, Rect outFrame, Rect outContentInsets,
             Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame,
             DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
-            SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
+            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+            Point outSurfaceSize) {
         int result = 0;
         boolean configChanged;
         final int pid = Binder.getCallingPid();
@@ -2359,6 +2362,10 @@
                 displayContent.sendNewConfiguration();
                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             }
+            if (winAnimator.mSurfaceController != null) {
+                outSurfaceSize.set(winAnimator.mSurfaceController.getWidth(),
+                                         winAnimator.mSurfaceController.getHeight());
+            }
         }
 
         Binder.restoreCallingIdentity(origId);
@@ -2412,8 +2419,8 @@
         return focusMayChange;
     }
 
-    private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win,
-            WindowStateAnimator winAnimator) {
+    private int createSurfaceControl(SurfaceControl outSurfaceControl,
+            int result, WindowState win, WindowStateAnimator winAnimator) {
         if (!win.mHasSurface) {
             result |= RELAYOUT_RES_SURFACE_CHANGED;
         }
@@ -2692,8 +2699,7 @@
         displayContent.getDockedDividerController().checkMinimizeChanged(animate);
     }
 
-    boolean isValidPictureInPictureAspectRatio(int displayId, float aspectRatio) {
-        final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+    boolean isValidPictureInPictureAspectRatio(DisplayContent displayContent, float aspectRatio) {
         return displayContent.getPinnedStackController().isValidPictureInPictureAspectRatio(
                 aspectRatio);
     }
@@ -2765,7 +2771,7 @@
         synchronized (mGlobalLock) {
             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
             if (displayContent != null && mRoot.getTopChild() != displayContent) {
-                mRoot.positionChildAt(WindowContainer.POSITION_TOP, displayContent,
+                displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
                         true /* includingParents */);
             }
         }
@@ -5992,12 +5998,10 @@
                     pw.print(" apps="); pw.print(mAppsFreezingScreen);
             final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
             pw.print("  mRotation="); pw.print(defaultDisplayContent.getRotation());
-            pw.print("  mLastWindowForcedOrientation=");
-                    pw.print(defaultDisplayContent.getLastWindowForcedOrientation());
-                    pw.print(" mLastOrientation=");
-                            pw.println(defaultDisplayContent.getLastOrientation());
-                    pw.print(" waitingForConfig=");
-                            pw.println(defaultDisplayContent.mWaitingForConfig);
+            pw.print("  mLastOrientation=");
+                    pw.println(defaultDisplayContent.getLastOrientation());
+            pw.print(" waitingForConfig=");
+                    pw.println(defaultDisplayContent.mWaitingForConfig);
 
             pw.print("  Animation settings: disabled="); pw.print(mAnimationsDisabled);
                     pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
@@ -7692,7 +7696,7 @@
 
         final DisplayContent displayContent = touchedWindow.getDisplayContent();
         if (!displayContent.isOnTop()) {
-            displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP, displayContent,
+            displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
                     true /* includingParents */);
         }
         handleTaskFocusChange(touchedWindow.getTask());
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index ceb38f7..c755e60 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -971,11 +971,11 @@
         mAtm.mH.sendMessageAtFrontOfQueue(m);
     }
 
-    public void appDied() {
+    void appDied(String reason) {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
         final Message m = PooledLambda.obtainMessage(
-                WindowProcessListener::appDied, mListener);
+                WindowProcessListener::appDied, mListener, reason);
         mAtm.mH.sendMessage(m);
     }
 
@@ -1136,6 +1136,7 @@
     }
 
     public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
+        Runnable targetRunnable = null;
         synchronized (mAtm.mGlobalLock) {
             if (mAtm.mController == null) {
                 return;
@@ -1145,13 +1146,16 @@
                 // 0 == continue, -1 = kill process immediately
                 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
                 if (res < 0 && mPid != MY_PID) {
-                    killAppCallback.run();
+                    targetRunnable = killAppCallback;
                 }
             } catch (RemoteException e) {
                 mAtm.mController = null;
                 Watchdog.getInstance().setActivityController(null);
             }
         }
+        if (targetRunnable != null) {
+            targetRunnable.run();
+        }
     }
 
     public boolean appNotResponding(String info, Runnable killAppCallback,
@@ -1179,6 +1183,7 @@
             }
         }
         if (targetRunnable != null) {
+            // Execute runnable outside WM lock since the runnable will hold AM lock
             targetRunnable.run();
             return true;
         }
diff --git a/services/core/java/com/android/server/wm/WindowProcessListener.java b/services/core/java/com/android/server/wm/WindowProcessListener.java
index 870cbb0..9505191 100644
--- a/services/core/java/com/android/server/wm/WindowProcessListener.java
+++ b/services/core/java/com/android/server/wm/WindowProcessListener.java
@@ -59,7 +59,7 @@
             long versionCode);
 
     /** App died :(...oh well */
-    void appDied();
+    void appDied(String reason);
     void dumpDebug(ProtoOutputStream proto, long fieldId);
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a4297416..2965764 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -73,6 +73,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
 import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
@@ -3210,6 +3211,7 @@
             case TYPE_PRIORITY_PHONE:
             case TYPE_SEARCH_BAR:
             case TYPE_STATUS_BAR:
+            case TYPE_NOTIFICATION_SHADE:
             case TYPE_STATUS_BAR_PANEL:
             case TYPE_STATUS_BAR_SUB_PANEL:
             case TYPE_SYSTEM_DIALOG:
@@ -5011,7 +5013,7 @@
     }
 
     private void startAnimation(Transaction t, AnimationAdapter adapter) {
-        startAnimation(t, adapter, mWinAnimator.mLastHidden);
+        startAnimation(t, adapter, mWinAnimator.mLastHidden, null /* animationFinishedCallback */);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 486616d..6189fbd 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -272,7 +272,8 @@
 
         mWin.checkPolicyVisibilityChange();
         final DisplayContent displayContent = mWin.getDisplayContent();
-        if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.isVisibleByPolicy()) {
+        if ((mAttrType == LayoutParams.TYPE_STATUS_BAR
+                || mAttrType == LayoutParams.TYPE_NOTIFICATION_SHADE) && mWin.isVisibleByPolicy()) {
             // Upon completion of a not-visible to visible status bar animation a relayout is
             // required.
             displayContent.setLayoutNeeded();
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 2a1e980..43cd66d 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
@@ -38,7 +39,9 @@
 import android.os.Debug;
 import android.os.IBinder;
 import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
 
+import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.protolog.common.ProtoLog;
 
 import java.io.PrintWriter;
@@ -228,12 +231,6 @@
         return false;
     }
 
-    ActivityRecord asActivityRecord() {
-        // TODO: Not sure if this is the best way to handle this vs. using instanceof and casting.
-        // I am not an app window token!
-        return null;
-    }
-
     @Override
     void removeImmediately() {
         if (mDisplayContent != null) {
@@ -256,6 +253,27 @@
         super.onDisplayChanged(dc);
     }
 
+    @Override
+    void assignLayer(SurfaceControl.Transaction t, int layer) {
+        if (windowType == TYPE_DOCK_DIVIDER) {
+            // See {@link DisplayContent#mSplitScreenDividerAnchor}
+            super.assignRelativeLayer(t, mDisplayContent.getSplitScreenDividerAnchor(), 1);
+        } else if (mRoundedCornerOverlay) {
+            super.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
+        } else {
+            super.assignLayer(t, layer);
+        }
+    }
+
+    @Override
+    SurfaceControl.Builder makeSurface() {
+        final SurfaceControl.Builder builder = super.makeSurface();
+        if (mRoundedCornerOverlay) {
+            builder.setParent(null);
+        }
+        return builder;
+    }
+
     @CallSuper
     @Override
     public void dumpDebug(ProtoOutputStream proto, long fieldId,
@@ -315,4 +333,8 @@
                 mOwnerCanManageAppTokens);
         return mOwnerCanManageAppTokens && (layer > navLayer);
     }
+
+    int getWindowLayerFromType() {
+        return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java
new file mode 100644
index 0000000..0c09c88
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
+import android.graphics.GraphicBuffer;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+
+/** Helper functions for the {@link com.android.server.wm.ScreenRotationAnimation} class*/
+public class RotationAnimationUtils {
+
+    /**
+     * Converts the provided {@link GraphicBuffer} and converts it to a bitmap to then sample the
+     * luminance at the borders of the bitmap
+     * @return the average luminance of all the pixels at the borders of the bitmap
+     */
+    public static float getAvgBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
+        Bitmap hwBitmap = Bitmap.wrapHardwareBuffer(graphicBuffer, colorSpace);
+        if (hwBitmap == null) {
+            return 0;
+        }
+
+        Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false);
+        float totalLuma = 0;
+        int height = swaBitmap.getHeight();
+        int width = swaBitmap.getWidth();
+        int i;
+        for (i = 0; i < width; i++) {
+            totalLuma += swaBitmap.getColor(i, 0).luminance();
+            totalLuma += swaBitmap.getColor(i, height - 1).luminance();
+        }
+        for (i = 0; i < height; i++) {
+            totalLuma += swaBitmap.getColor(0, i).luminance();
+            totalLuma += swaBitmap.getColor(width - 1, i).luminance();
+        }
+        return totalLuma / (2 * width + 2 * height);
+    }
+
+    /**
+     * Gets the average border luma by taking a screenshot of the {@param surfaceControl}.
+     * @see #getAvgBorderLuma(GraphicBuffer, ColorSpace)
+     */
+    public static float getLumaOfSurfaceControl(Display display, SurfaceControl surfaceControl) {
+        if (surfaceControl ==  null) {
+            return 0;
+        }
+
+        Point size = new Point();
+        display.getSize(size);
+        Rect crop = new Rect(0, 0, size.x, size.y);
+        SurfaceControl.ScreenshotGraphicBuffer buffer =
+                SurfaceControl.captureLayers(surfaceControl, crop, 1);
+        if (buffer == null) {
+            return 0;
+        }
+
+        return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(),
+                buffer.getColorSpace());
+    }
+
+    public static void createRotationMatrix(int rotation, int width, int height, Matrix outMatrix) {
+        switch (rotation) {
+            case Surface.ROTATION_0:
+                outMatrix.reset();
+                break;
+            case Surface.ROTATION_90:
+                outMatrix.setRotate(90, 0, 0);
+                outMatrix.postTranslate(height, 0);
+                break;
+            case Surface.ROTATION_180:
+                outMatrix.setRotate(180, 0, 0);
+                outMatrix.postTranslate(width, height);
+                break;
+            case Surface.ROTATION_270:
+                outMatrix.setRotate(270, 0, 0);
+                outMatrix.postTranslate(0, width);
+                break;
+        }
+    }
+}
diff --git a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
index 9cd743b..8b6526f 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
@@ -20,6 +20,7 @@
 #include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <vector>
 
 #include <jni.h>
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 14bd72b..4b90027 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2556,7 +2556,7 @@
         }
         for (final String restriction : doAdmin.userRestrictions.keySet()) {
             if (UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange(restriction)) {
-                parentAdmin.userRestrictions.putBoolean(
+                parentAdmin.ensureUserRestrictions().putBoolean(
                         restriction, doAdmin.userRestrictions.getBoolean(restriction));
             }
         }
@@ -10151,10 +10151,14 @@
                             UserHandle.myUserId(), ACTION_PROVISION_MANAGED_USER).toArray(
                             new String[0]);
                 }
-                UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name,
-                        userType, userInfoFlags, disallowedPackages);
-                if (userInfo != null) {
-                    user = userInfo.getUserHandle();
+                try {
+                    UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name,
+                            userType, userInfoFlags, disallowedPackages);
+                    if (userInfo != null) {
+                        user = userInfo.getUserHandle();
+                    }
+                } catch (UserManager.CheckedUserOperationException e) {
+                    Log.e(LOG_TAG, "Couldn't createUserEvenWhenDisallowed", e);
                 }
             } finally {
                 mInjector.binderRestoreCallingIdentity(id);
@@ -11344,6 +11348,37 @@
     }
 
     @Override
+    public void setLockdownAdminConfiguredNetworks(ComponentName who, boolean lockdown) {
+        if (!mHasFeature) {
+            return;
+        }
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        enforceDeviceOwnerOrProfileOwnerOnOrganizationOwnedDevice(who);
+
+        mInjector.binderWithCleanCallingIdentity(() ->
+                mInjector.settingsGlobalPutInt(Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN,
+                        lockdown ? 1 : 0));
+
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS)
+                .setAdmin(who)
+                .setBoolean(lockdown)
+                .write();
+    }
+
+    @Override
+    public boolean isLockdownAdminConfiguredNetworks(ComponentName who) {
+        if (!mHasFeature) {
+            return false;
+        }
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        enforceDeviceOwnerOrProfileOwnerOnOrganizationOwnedDevice(who);
+
+        return mInjector.binderWithCleanCallingIdentity(() ->
+                mInjector.settingsGlobalGetInt(Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) > 0);
+    }
+
+    @Override
     public void setLocationEnabled(ComponentName who, boolean locationEnabled) {
         Objects.requireNonNull(who, "ComponentName is null");
         enforceDeviceOwner(who);
diff --git a/services/java/com/android/server/SystemConfigService.java b/services/java/com/android/server/SystemConfigService.java
new file mode 100644
index 0000000..e8ab101
--- /dev/null
+++ b/services/java/com/android/server/SystemConfigService.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server;
+
+import android.Manifest;
+import android.content.Context;
+import android.os.ISystemConfig;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service class that runs inside the system_server process to handle queries to
+ * {@link com.android.server.SystemConfig}.
+ * @hide
+ */
+public class SystemConfigService extends SystemService {
+    private final Context mContext;
+
+    private final ISystemConfig.Stub mInterface = new ISystemConfig.Stub() {
+        @Override
+        public List<String> getDisabledUntilUsedPreinstalledCarrierApps() {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_CARRIER_APP_INFO,
+                    "getDisabledUntilUsedPreInstalledCarrierApps requires READ_CARRIER_APP_INFO");
+            return new ArrayList<>(
+                    SystemConfig.getInstance().getDisabledUntilUsedPreinstalledCarrierApps());
+        }
+
+        @Override
+        public Map getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_CARRIER_APP_INFO,
+                    "getDisabledUntilUsedPreInstalledCarrierAssociatedApps requires"
+                            + " READ_CARRIER_APP_INFO");
+            return SystemConfig.getInstance()
+                    .getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+        }
+    };
+
+    public SystemConfigService(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.SYSTEM_CONFIG_SERVICE, mInterface);
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 109a6fd..0b7c359 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -223,8 +223,14 @@
             "com.android.server.usb.UsbService$Lifecycle";
     private static final String MIDI_SERVICE_CLASS =
             "com.android.server.midi.MidiService$Lifecycle";
+    private static final String WIFI_APEX_SERVICE_JAR_PATH =
+            "/apex/com.android.wifi/javalib/wifi-service.jar";
     private static final String WIFI_SERVICE_CLASS =
             "com.android.server.wifi.WifiService";
+    private static final String WIFI_SCANNING_SERVICE_CLASS =
+            "com.android.server.wifi.scanner.WifiScanningService";
+    private static final String WIFI_RTT_SERVICE_CLASS =
+            "com.android.server.wifi.rtt.RttService";
     private static final String WIFI_AWARE_SERVICE_CLASS =
             "com.android.server.wifi.aware.WifiAwareService";
     private static final String WIFI_P2P_SERVICE_CLASS =
@@ -896,6 +902,11 @@
     private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
         t.traceBegin("startCoreServices");
 
+        // Service for system config
+        t.traceBegin("StartSystemConfigService");
+        mSystemServiceManager.startService(SystemConfigService.class);
+        t.traceEnd();
+
         t.traceBegin("StartBatteryService");
         // Tracks the battery level.  Requires LightService.
         mSystemServiceManager.startService(BatteryService.class);
@@ -1426,33 +1437,36 @@
                     PackageManager.FEATURE_WIFI)) {
                 // Wifi Service must be started first for wifi-related services.
                 t.traceBegin("StartWifi");
-                mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
+                mSystemServiceManager.startServiceFromJar(
+                        WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
                 t.traceBegin("StartWifiScanning");
-                mSystemServiceManager.startService(
-                        "com.android.server.wifi.scanner.WifiScanningService");
+                mSystemServiceManager.startServiceFromJar(
+                        WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI_RTT)) {
                 t.traceBegin("StartRttService");
-                mSystemServiceManager.startService(
-                        "com.android.server.wifi.rtt.RttService");
+                mSystemServiceManager.startServiceFromJar(
+                        WIFI_RTT_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI_AWARE)) {
                 t.traceBegin("StartWifiAware");
-                mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
+                mSystemServiceManager.startServiceFromJar(
+                        WIFI_AWARE_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI_DIRECT)) {
                 t.traceBegin("StartWifiP2P");
-                mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
+                mSystemServiceManager.startServiceFromJar(
+                        WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
             }
 
@@ -1755,7 +1769,7 @@
             if (!isWatch && !disableNetworkTime) {
                 t.traceBegin("StartNetworkTimeUpdateService");
                 try {
-                    networkTimeUpdater = new NetworkTimeUpdateServiceImpl(context);
+                    networkTimeUpdater = new NetworkTimeUpdateService(context);
                     ServiceManager.addService("network_time_update_service", networkTimeUpdater);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkTimeUpdate service", e);
diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp
index 3ce514a..d2f86ee 100644
--- a/services/robotests/Android.bp
+++ b/services/robotests/Android.bp
@@ -43,6 +43,9 @@
         "platform-test-annotations",
         "testng",
     ],
+    static_libs: [
+        "androidx.test.ext.truth",
+    ],
 
     instrumentation_for: "FrameworksServicesLib",
 }
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index 2510b60..ec56e1e 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -131,6 +131,7 @@
 import org.mockito.ArgumentMatcher;
 import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -2339,6 +2340,85 @@
         assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L);
     }
 
+    /** Do not inform transport of an empty backup if the app hasn't backed up before */
+    @Test
+    public void testRunTask_whenNoDataToBackupOnFirstBackup_doesNotTellTransportOfBackup()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        mBackupManagerService.setCurrentToken(0L);
+        when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L);
+        setUpAgent(PACKAGE_1);
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1);
+
+        runTask(task);
+
+        verify(transportMock.transport, never())
+                .performBackup(
+                        argThat(packageInfo(PACKAGE_1)), any(ParcelFileDescriptor.class), anyInt());
+    }
+
+    /** Let the transport know if there are no changes for a KV backed-up package. */
+    @Test
+    public void testRunTask_whenBackupHasCompletedAndThenNoDataChanges_transportGetsNotified()
+            throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L);
+        when(transportMock.transport.isAppEligibleForBackup(
+                        argThat(packageInfo(PACKAGE_1)), eq(false)))
+                .thenReturn(true);
+        when(transportMock.transport.isAppEligibleForBackup(
+                        argThat(packageInfo(PACKAGE_2)), eq(false)))
+                .thenReturn(true);
+        setUpAgentWithData(PACKAGE_1);
+        setUpAgentWithData(PACKAGE_2);
+
+        PackageInfo endSentinel = new PackageInfo();
+        endSentinel.packageName = KeyValueBackupTask.NO_DATA_END_SENTINEL;
+
+        // Perform First Backup run, which should backup both packages
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1, PACKAGE_2);
+        runTask(task);
+        InOrder order = Mockito.inOrder(transportMock.transport);
+        order.verify(transportMock.transport)
+                .performBackup(
+                        argThat(packageInfo(PACKAGE_1)),
+                        any(),
+                        eq(BackupTransport.FLAG_NON_INCREMENTAL));
+        order.verify(transportMock.transport).finishBackup();
+        order.verify(transportMock.transport)
+                .performBackup(
+                        argThat(packageInfo(PACKAGE_2)),
+                        any(),
+                        eq(BackupTransport.FLAG_NON_INCREMENTAL));
+        order.verify(transportMock.transport).finishBackup();
+
+        // Run again with new data for package 1, but nothing new for package 2
+        task = createKeyValueBackupTask(transportMock, PACKAGE_1);
+        runTask(task);
+
+        // Now for the second run we performed one incremental backup (package 1) and
+        // made one "no change" call (package 2) before sending the end sentinel.
+        order.verify(transportMock.transport)
+                .performBackup(
+                        argThat(packageInfo(PACKAGE_1)),
+                        any(),
+                        eq(BackupTransport.FLAG_INCREMENTAL));
+        order.verify(transportMock.transport).finishBackup();
+        order.verify(transportMock.transport)
+                .performBackup(
+                        argThat(packageInfo(PACKAGE_2)),
+                        any(),
+                        eq(BackupTransport.FLAG_DATA_NOT_CHANGED));
+        order.verify(transportMock.transport).finishBackup();
+        order.verify(transportMock.transport)
+                .performBackup(
+                        argThat(packageInfo(endSentinel)),
+                        any(),
+                        eq(BackupTransport.FLAG_DATA_NOT_CHANGED));
+        order.verify(transportMock.transport).finishBackup();
+        order.verifyNoMoreInteractions();
+    }
+
     private void runTask(KeyValueBackupTask task) {
         // Pretend we are not on the main-thread to prevent RemoteCall from complaining
         mShadowMainLooper.setCurrentThread(false);
@@ -2576,6 +2656,20 @@
                 packageInfo != null && packageData.packageName.equals(packageInfo.packageName);
     }
 
+    /** Matches {@link PackageInfo} whose package name is {@code packageData.packageName}. */
+    private static ArgumentMatcher<PackageInfo> packageInfo(PackageInfo packageData) {
+        // We have to test for packageInfo nulity because of Mockito's own stubbing with argThat().
+        // E.g. if you do:
+        //
+        //   1. when(object.method(argThat(str -> str.equals("foo")))).thenReturn(0)
+        //   2. when(object.method(argThat(str -> str.equals("bar")))).thenReturn(2)
+        //
+        // The second line will throw NPE because it will call lambda 1 with null, since argThat()
+        // returns null. So we guard against that by checking for null.
+        return packageInfo ->
+                packageInfo != null && packageInfo.packageName.equals(packageInfo.packageName);
+    }
+
     /** Matches {@link ApplicationInfo} whose package name is {@code packageData.packageName}. */
     private static ArgumentMatcher<ApplicationInfo> applicationInfo(PackageData packageData) {
         return applicationInfo ->
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
new file mode 100644
index 0000000..ce088643
--- /dev/null
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OP_INTERACT_ACROSS_PROFILES;
+import static android.content.Intent.FLAG_RECEIVER_REGISTERED_ONLY;
+import static android.content.pm.CrossProfileApps.ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.Manifest;
+import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
+import android.app.AppOpsManager;
+import android.app.AppOpsManager.Mode;
+import android.app.admin.DevicePolicyManagerInternal;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.LocalServices;
+import com.android.server.testing.shadows.ShadowApplicationPackageManager;
+import com.android.server.testing.shadows.ShadowUserManager;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import com.google.android.collect.Lists;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/** Unit tests for {@link CrossProfileAppsServiceImpl}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+@Config(shadows = {ShadowUserManager.class, ShadowApplicationPackageManager.class})
+public class CrossProfileAppsServiceImplRoboTest {
+    private static final int CALLING_UID = 1111;
+    private static final String CROSS_PROFILE_APP_PACKAGE_NAME =
+            "com.android.server.pm.crossprofileappsserviceimplrobotest.crossprofileapp";
+    private static final int PERSONAL_PROFILE_USER_ID = 0;
+    private static final int PERSONAL_PROFILE_UID = 2222;
+    private static final int WORK_PROFILE_USER_ID = 10;
+    private static final int WORK_PROFILE_UID = 3333;
+    private static final int OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID = 20;
+
+    private final ContextWrapper mContext = ApplicationProvider.getApplicationContext();
+    private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
+    private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+    private final PackageManager mPackageManager = mContext.getPackageManager();
+    private final TestInjector mInjector = new TestInjector();
+    private final CrossProfileAppsServiceImpl mCrossProfileAppsServiceImpl =
+            new CrossProfileAppsServiceImpl(mContext, mInjector);
+    private final Map<UserHandle, Set<Intent>> mSentUserBroadcasts = new HashMap<>();
+
+    @Mock private PackageManagerInternal mPackageManagerInternal;
+    @Mock private IPackageManager mIPackageManager;
+    @Mock private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
+
+    @Before
+    public void initializeMocks() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mockCrossProfileAppInstalledAndEnabledOnEachProfile();
+        mockCrossProfileAppRequestsInteractAcrossProfiles();
+        mockCrossProfileAppWhitelisted();
+    }
+
+    private void mockCrossProfileAppInstalledAndEnabledOnEachProfile() {
+        // They are enabled by default, so we simply have to ensure that a package info with an
+        // application info is returned.
+        final PackageInfo packageInfo = buildTestPackageInfo();
+        when(mPackageManagerInternal.getPackageInfo(
+                        eq(CROSS_PROFILE_APP_PACKAGE_NAME),
+                        /* flags= */ anyInt(),
+                        /* filterCallingUid= */ anyInt(),
+                        eq(PERSONAL_PROFILE_USER_ID)))
+                .thenReturn(packageInfo);
+        when(mPackageManagerInternal.getPackageInfo(
+                        eq(CROSS_PROFILE_APP_PACKAGE_NAME),
+                        /* flags= */ anyInt(),
+                        /* filterCallingUid= */ anyInt(),
+                        eq(WORK_PROFILE_USER_ID)))
+                .thenReturn(packageInfo);
+        mockCrossProfileAndroidPackage(PackageImpl.forParsing(CROSS_PROFILE_APP_PACKAGE_NAME));
+    }
+
+    private PackageInfo buildTestPackageInfo() {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        return packageInfo;
+    }
+
+    private void mockCrossProfileAppRequestsInteractAcrossProfiles() throws Exception {
+        final String permissionName = Manifest.permission.INTERACT_ACROSS_PROFILES;
+        when(mIPackageManager.getAppOpPermissionPackages(permissionName))
+                .thenReturn(new String[] {CROSS_PROFILE_APP_PACKAGE_NAME});
+    }
+
+    private void mockCrossProfileAppWhitelisted() {
+        when(mDevicePolicyManagerInternal.getAllCrossProfilePackages())
+                .thenReturn(Lists.newArrayList(CROSS_PROFILE_APP_PACKAGE_NAME));
+    }
+
+    @Before
+    public void setUpCrossProfileAppUidsAndPackageNames() {
+        ShadowApplicationPackageManager.setPackageUidAsUser(
+                CROSS_PROFILE_APP_PACKAGE_NAME, PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID);
+        ShadowApplicationPackageManager.setPackageUidAsUser(
+                CROSS_PROFILE_APP_PACKAGE_NAME, WORK_PROFILE_UID, WORK_PROFILE_USER_ID);
+    }
+
+    @Before
+    public void grantPermissions() {
+        grantPermissions(
+                Manifest.permission.MANAGE_APP_OPS_MODES,
+                Manifest.permission.INTERACT_ACROSS_USERS,
+                Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+    }
+
+    @Before
+    public void setUpProfiles() {
+        final ShadowUserManager shadowUserManager = Shadow.extract(mUserManager);
+        shadowUserManager.addProfileIds(
+                PERSONAL_PROFILE_USER_ID,
+                WORK_PROFILE_USER_ID,
+                OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID);
+    }
+
+    @Before
+    public void setInteractAcrossProfilesAppOpDefault() {
+        // It seems to be necessary to provide the shadow with the default already specified in
+        // AppOpsManager.
+        final int defaultMode = AppOpsManager.opToDefaultMode(OP_INTERACT_ACROSS_PROFILES);
+        explicitlySetInteractAcrossProfilesAppOp(PERSONAL_PROFILE_UID, defaultMode);
+        explicitlySetInteractAcrossProfilesAppOp(WORK_PROFILE_UID, defaultMode);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_missingInteractAcrossUsersAndFull_throwsSecurityException() {
+        denyPermissions(Manifest.permission.INTERACT_ACROSS_USERS);
+        denyPermissions(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+        try {
+            mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                    CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+            fail();
+        } catch (SecurityException expected) {}
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_missingManageAppOpsModes_throwsSecurityException() {
+        denyPermissions(Manifest.permission.MANAGE_APP_OPS_MODES);
+        try {
+            mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                    CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+            fail();
+        } catch (SecurityException expected) {}
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_setsAppOp() {
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(getCrossProfileAppOp()).isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_setsAppOpWithUsersAndWithoutFull() {
+        denyPermissions(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(getCrossProfileAppOp()).isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_setsAppOpWithFullAndWithoutUsers() {
+        denyPermissions(Manifest.permission.INTERACT_ACROSS_USERS);
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(getCrossProfileAppOp()).isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_setsAppOpOnOtherProfile() {
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(getCrossProfileAppOp(WORK_PROFILE_UID)).isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_sendsBroadcast() {
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedCanInteractAcrossProfilesChangedBroadcast()).isTrue();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_sendsBroadcastToOtherProfile() {
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedCanInteractAcrossProfilesChangedBroadcast(WORK_PROFILE_USER_ID))
+                .isTrue();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_doesNotSendBroadcastToProfileWithoutPackage() {
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedCanInteractAcrossProfilesChangedBroadcast(
+                        OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID))
+                .isFalse();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_toSameAsCurrent_doesNotSendBroadcast() {
+        explicitlySetInteractAcrossProfilesAppOp(MODE_ALLOWED);
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedCanInteractAcrossProfilesChangedBroadcast()).isFalse();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_toAllowed_whenNotAbleToRequest_doesNotSet() {
+        mockCrossProfileAppNotWhitelisted();
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(getCrossProfileAppOp()).isNotEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_toAllowed_whenNotAbleToRequest_doesNotSendBroadcast() {
+        mockCrossProfileAppNotWhitelisted();
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedCanInteractAcrossProfilesChangedBroadcast()).isFalse();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_withoutCrossProfileAttribute_manifestReceiversDoNotGetBroadcast() {
+        declareCrossProfileAttributeOnCrossProfileApp(false);
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedManifestCanInteractAcrossProfilesChangedBroadcast()).isFalse();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_withCrossProfileAttribute_manifestReceiversGetBroadcast() {
+        declareCrossProfileAttributeOnCrossProfileApp(true);
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(receivedManifestCanInteractAcrossProfilesChangedBroadcast()).isTrue();
+    }
+
+    private void explicitlySetInteractAcrossProfilesAppOp(@Mode int mode) {
+        explicitlySetInteractAcrossProfilesAppOp(PERSONAL_PROFILE_UID, mode);
+    }
+
+    private void explicitlySetInteractAcrossProfilesAppOp(int uid, @Mode int mode) {
+        shadowOf(mAppOpsManager).setMode(
+                OP_INTERACT_ACROSS_PROFILES, uid, CROSS_PROFILE_APP_PACKAGE_NAME, mode);
+    }
+
+    private void grantPermissions(String... permissions) {
+        shadowOf(mContext).grantPermissions(Process.myPid(), CALLING_UID, permissions);
+    }
+
+    private void denyPermissions(String... permissions) {
+        shadowOf(mContext).denyPermissions(Process.myPid(), CALLING_UID, permissions);
+    }
+
+
+    private @Mode int getCrossProfileAppOp() {
+        return getCrossProfileAppOp(PERSONAL_PROFILE_UID);
+    }
+
+    private @Mode int getCrossProfileAppOp(int uid) {
+        return mAppOpsManager.unsafeCheckOpNoThrow(
+                AppOpsManager.permissionToOp(Manifest.permission.INTERACT_ACROSS_PROFILES),
+                uid,
+                CROSS_PROFILE_APP_PACKAGE_NAME);
+    }
+
+    private boolean receivedCanInteractAcrossProfilesChangedBroadcast() {
+        return receivedCanInteractAcrossProfilesChangedBroadcast(PERSONAL_PROFILE_USER_ID);
+    }
+
+    private boolean receivedCanInteractAcrossProfilesChangedBroadcast(@UserIdInt int userId) {
+        final UserHandle userHandle = UserHandle.of(userId);
+        if (!mSentUserBroadcasts.containsKey(userHandle)) {
+            return false;
+        }
+        return mSentUserBroadcasts.get(userHandle)
+                .stream()
+                .anyMatch(this::isBroadcastCanInteractAcrossProfilesChanged);
+    }
+
+    private boolean isBroadcastCanInteractAcrossProfilesChanged(Intent intent) {
+        return intent.getAction().equals(ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED)
+                && CROSS_PROFILE_APP_PACKAGE_NAME.equals(intent.getPackage());
+    }
+
+    private void mockCrossProfileAndroidPackage(AndroidPackage androidPackage) {
+        when(mPackageManagerInternal.getPackage(CROSS_PROFILE_APP_PACKAGE_NAME))
+                .thenReturn(androidPackage);
+        when(mPackageManagerInternal.getPackage(PERSONAL_PROFILE_UID)).thenReturn(androidPackage);
+        when(mPackageManagerInternal.getPackage(WORK_PROFILE_UID)).thenReturn(androidPackage);
+    }
+
+    private void mockCrossProfileAppNotWhitelisted() {
+        when(mDevicePolicyManagerInternal.getAllCrossProfilePackages())
+                .thenReturn(new ArrayList<>());
+    }
+
+    private boolean receivedManifestCanInteractAcrossProfilesChangedBroadcast() {
+        final UserHandle userHandle = UserHandle.of(PERSONAL_PROFILE_USER_ID);
+        if (!mSentUserBroadcasts.containsKey(userHandle)) {
+            return false;
+        }
+        return mSentUserBroadcasts.get(userHandle)
+                .stream()
+                .anyMatch(this::isBroadcastManifestCanInteractAcrossProfilesChanged);
+    }
+
+    private boolean isBroadcastManifestCanInteractAcrossProfilesChanged(Intent intent) {
+        // The manifest check is negative since the FLAG_RECEIVER_REGISTERED_ONLY flag means that
+        // manifest receivers can NOT receive the broadcast.
+        return isBroadcastCanInteractAcrossProfilesChanged(intent)
+                && (intent.getFlags() & FLAG_RECEIVER_REGISTERED_ONLY) == 0;
+    }
+
+    private void declareCrossProfileAttributeOnCrossProfileApp(boolean value) {
+        mockCrossProfileAndroidPackage(
+                PackageImpl.forParsing(CROSS_PROFILE_APP_PACKAGE_NAME).setCrossProfile(value));
+    }
+
+    private class TestInjector implements CrossProfileAppsServiceImpl.Injector {
+
+        @Override
+        public int getCallingUid() {
+            return CALLING_UID;
+        }
+
+        @Override
+        public @UserIdInt int getCallingUserId() {
+            return PERSONAL_PROFILE_USER_ID;
+        }
+
+        @Override
+        public UserHandle getCallingUserHandle() {
+            return UserHandle.of(getCallingUserId());
+        }
+
+        @Override
+        public long clearCallingIdentity() {
+            return 0;
+        }
+
+        @Override
+        public void restoreCallingIdentity(long token) {}
+
+        @Override
+        public UserManager getUserManager() {
+            return mUserManager;
+        }
+
+        @Override
+        public PackageManagerInternal getPackageManagerInternal() {
+            return mPackageManagerInternal;
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mPackageManager;
+        }
+
+        @Override
+        public AppOpsManager getAppOpsManager() {
+            return mAppOpsManager;
+        }
+
+        @Override
+        public ActivityManagerInternal getActivityManagerInternal() {
+            return LocalServices.getService(ActivityManagerInternal.class);
+        }
+
+        @Override
+        public ActivityTaskManagerInternal getActivityTaskManagerInternal() {
+            return LocalServices.getService(ActivityTaskManagerInternal.class);
+        }
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return mIPackageManager;
+        }
+
+        @Override
+        public DevicePolicyManagerInternal getDevicePolicyManagerInternal() {
+            return mDevicePolicyManagerInternal;
+        }
+
+        @Override
+        public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+            // Robolectric's shadows do not currently support sendBroadcastAsUser.
+            final Set<Intent> broadcasts =
+                    mSentUserBroadcasts.containsKey(user)
+                            ? mSentUserBroadcasts.get(user)
+                            : new HashSet<>();
+            broadcasts.add(intent);
+            mSentUserBroadcasts.put(user, broadcasts);
+            mContext.sendBroadcastAsUser(intent, user);
+        }
+
+        @Override
+        public int checkComponentPermission(
+                String permission, int uid, int owningUid, boolean exported) {
+            // ActivityManager#checkComponentPermission calls through to
+            // AppGlobals.getPackageManager()#checkUidPermission, which calls through to
+            // ShadowActivityThread with Robolectric. This method is currently not supported there.
+            return mContext.checkPermission(permission, Process.myPid(), uid);
+        }
+    }
+}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
index ab121ed..1443eab 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
@@ -26,6 +26,7 @@
 import org.robolectric.annotation.Resetter;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -39,6 +40,7 @@
     private static final Map<String, PackageInfo> sPackageInfos = new ArrayMap<>();
     private static final List<PackageInfo> sInstalledPackages = new ArrayList<>();
     private static final Map<String, Integer> sPackageUids = new ArrayMap<>();
+    private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>();
 
     /**
      * Registers the package {@code packageName} to be returned when invoking {@link
@@ -58,6 +60,19 @@
         sPackageUids.put(packageName, packageUid);
     }
 
+    /**
+     * Sets the package uid {@code packageUid} for the package {@code packageName} to be returned
+     * when invoking {@link ApplicationPackageManager#getPackageUidAsUser(String, int, int)}.
+     */
+    public static void setPackageUidAsUser(String packageName, int packageUid, int userId) {
+        final Map<String, Integer> userPackageUids =
+                sUserPackageUids.containsKey(userId)
+                        ? sUserPackageUids.get(userId)
+                        : new HashMap<>();
+        userPackageUids.put(packageName, packageUid);
+        sUserPackageUids.put(userId, userPackageUids);
+    }
+
     @Override
     protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
@@ -75,6 +90,10 @@
     @Override
     protected int getPackageUidAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
+        if (sUserPackageUids.containsKey(userId)
+                && sUserPackageUids.get(userId).containsKey(packageName)) {
+            return sUserPackageUids.get(userId).get(packageName);
+        }
         if (!sPackageUids.containsKey(packageName)) {
             throw new NameNotFoundException(packageName);
         }
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java
index c6ae1a1..a9e4ee5 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java
@@ -16,18 +16,46 @@
 
 package com.android.server.testing.shadows;
 
+import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.os.UserManager;
 
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 /** Shadow for {@link UserManager}. */
 @Implements(UserManager.class)
 public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
+    private final Map<Integer, Set<Integer>> profileIds = new HashMap<>();
+
     /** @see UserManager#isUserUnlocked() */
     @Implementation
     public boolean isUserUnlocked(@UserIdInt int userId) {
         return false;
     }
+
+    /** @see UserManager#getProfileIds(int, boolean) () */
+    @Implementation
+    @NonNull
+    public int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
+        // Currently, enabledOnly is ignored.
+        if (!profileIds.containsKey(userId)) {
+            return new int[] {userId};
+        }
+        return profileIds.get(userId).stream().mapToInt(Number::intValue).toArray();
+    }
+
+    /** Add a collection of profile IDs, all within the same profile group. */
+    public void addProfileIds(@UserIdInt int... userIds) {
+        final Set<Integer> profileGroup = new HashSet<>();
+        for (int userId : userIds) {
+            profileGroup.add(userId);
+            profileIds.put(userId, profileGroup);
+        }
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
new file mode 100644
index 0000000..8d2a152
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.server.am.ActivityManagerService.Injector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.app.ApplicationExitInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManagerInternal;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.system.OsConstants;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import com.android.server.ServiceThread;
+import com.android.server.appop.AppOpsService;
+import com.android.server.wm.ActivityTaskManagerService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+/**
+ * Test class for {@link android.app.ApplicationExitInfo}.
+ *
+ * Build/Install/Run:
+ *  atest ApplicationExitInfoTest
+ */
+@Presubmit
+public class ApplicationExitInfoTest {
+    private static final String TAG = ApplicationExitInfoTest.class.getSimpleName();
+
+    @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule();
+    @Mock private AppOpsService mAppOpsService;
+    @Mock private PackageManagerInternal mPackageManagerInt;
+
+    private Context mContext = getInstrumentation().getTargetContext();
+    private TestInjector mInjector;
+    private ActivityManagerService mAms;
+    private ProcessList mProcessList;
+    private AppExitInfoTracker mAppExitInfoTracker;
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        System.setProperty("dexmaker.share_classloader", "true");
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mProcessList = spy(new ProcessList());
+        mAppExitInfoTracker = spy(new AppExitInfoTracker());
+        setFieldValue(AppExitInfoTracker.class, mAppExitInfoTracker, "mIsolatedUidRecords",
+                spy(mAppExitInfoTracker.new IsolatedUidRecords()));
+        setFieldValue(AppExitInfoTracker.class, mAppExitInfoTracker, "mAppExitInfoSourceZygote",
+                spy(mAppExitInfoTracker.new AppExitInfoExternalSource("zygote", null)));
+        setFieldValue(AppExitInfoTracker.class, mAppExitInfoTracker, "mAppExitInfoSourceLmkd",
+                spy(mAppExitInfoTracker.new AppExitInfoExternalSource("lmkd",
+                ApplicationExitInfo.REASON_LOW_MEMORY)));
+        setFieldValue(ProcessList.class, mProcessList, "mAppExitInfoTracker", mAppExitInfoTracker);
+        mInjector = new TestInjector(mContext);
+        mAms = new ActivityManagerService(mInjector, mServiceThreadRule.getThread());
+        mAms.mActivityTaskManager = new ActivityTaskManagerService(mContext);
+        mAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper());
+        mAms.mAtmInternal = spy(mAms.mActivityTaskManager.getAtmInternal());
+        mAms.mPackageManagerInt = mPackageManagerInt;
+    }
+
+    @After
+    public void tearDown() {
+        mHandlerThread.quit();
+    }
+
+    private static <T> void setFieldValue(Class clazz, Object obj, String fieldName, T val) {
+        try {
+            Field field = clazz.getDeclaredField(fieldName);
+            field.setAccessible(true);
+            Field mfield = Field.class.getDeclaredField("accessFlags");
+            mfield.setAccessible(true);
+            mfield.setInt(field, mfield.getInt(field) & ~(Modifier.FINAL | Modifier.PRIVATE));
+            field.set(obj, val);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+        }
+    }
+
+    private void updateExitInfo(ProcessRecord app) {
+        ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecordLocked(app);
+        mAppExitInfoTracker.handleNoteProcessDiedLocked(raw);
+        mAppExitInfoTracker.recycleRawRecordLocked(raw);
+    }
+
+    private void noteAppKill(ProcessRecord app, int reason, int subReason, String msg) {
+        ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecordLocked(app);
+        raw.setReason(reason);
+        raw.setSubReason(subReason);
+        raw.setDescription(msg);
+        mAppExitInfoTracker.handleNoteAppKillLocked(raw);
+        mAppExitInfoTracker.recycleRawRecordLocked(raw);
+    }
+
+    @Test
+    public void testApplicationExitInfo() throws Exception {
+        mAppExitInfoTracker.clearProcessExitInfo(true);
+        mAppExitInfoTracker.mAppExitInfoLoaded = true;
+
+        // Test application calls System.exit()
+        doNothing().when(mAppExitInfoTracker).schedulePersistProcessExitInfo(anyBoolean());
+
+        final int app1Uid = 10123;
+        final int app1Pid1 = 12345;
+        final int app1Pid2 = 12346;
+        final int app1DefiningUid = 23456;
+        final int app1ConnectiongGroup = 10;
+        final int app1UidUser2 = 1010123;
+        final int app1PidUser2 = 12347;
+        final int app1Pss1 = 34567;
+        final int app1Rss1 = 45678;
+        final int app1Pss2 = 34568;
+        final int app1Rss2 = 45679;
+        final int app1Pss3 = 34569;
+        final int app1Rss3 = 45680;
+        final String app1ProcessName = "com.android.test.stub1:process";
+        final String app1PackageName = "com.android.test.stub1";
+
+        final long now1 = System.currentTimeMillis();
+        ProcessRecord app = makeProcessRecord(
+                app1Pid1,                    // pid
+                app1Uid,                     // uid
+                app1Uid,                     // packageUid
+                null,                        // definingUid
+                0,                           // connectionGroup
+                PROCESS_STATE_LAST_ACTIVITY, // procstate
+                app1Pss1,                    // pss
+                app1Rss1,                    // rss
+                app1ProcessName,             // processName
+                app1PackageName);            // packageName
+
+        // Case 1: basic System.exit() test
+        int exitCode = 5;
+        doReturn(new Pair<Long, Object>(now1, Integer.valueOf(makeExitStatus(exitCode))))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        doReturn(null)
+                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+                .remove(anyInt(), anyInt());
+        updateExitInfo(app);
+
+        ArrayList<ApplicationExitInfo> list = new ArrayList<ApplicationExitInfo>();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, app1Pid1, 0, list);
+        assertEquals(1, list.size());
+
+        ApplicationExitInfo info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                 // info
+                now1,                                 // timestamp
+                app1Pid1,                             // pid
+                app1Uid,                              // uid
+                app1Uid,                              // packageUid
+                null,                                 // definingUid
+                app1ProcessName,                      // processName
+                0,                                    // connectionGroup
+                ApplicationExitInfo.REASON_EXIT_SELF, // reason
+                null,                                 // subReason
+                exitCode,                             // status
+                app1Pss1,                             // pss
+                app1Rss1,                             // rss
+                IMPORTANCE_CACHED,                    // importance
+                null);                                // description
+
+        // Case 2: create another app1 process record with a different pid
+        sleep(1);
+        final long now2 = System.currentTimeMillis();
+        app = makeProcessRecord(
+                app1Pid2,               // pid
+                app1Uid,                // uid
+                app1Uid,                // packageUid
+                app1DefiningUid,        // definingUid
+                app1ConnectiongGroup,   // connectionGroup
+                PROCESS_STATE_RECEIVER, // procstate
+                app1Pss2,               // pss
+                app1Rss2,               // rss
+                app1ProcessName,        // processName
+                app1PackageName);       // packageName
+        exitCode = 6;
+        doReturn(new Pair<Long, Object>(now2, Integer.valueOf(makeExitStatus(exitCode))))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        updateExitInfo(app);
+        list.clear();
+
+        // Get all the records for app1Uid
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, 0, 0, list);
+        assertEquals(2, list.size());
+
+        info = list.get(0);
+
+        // Verify the most recent one
+        verifyApplicationExitInfo(
+                info,                                 // info
+                now2,                                 // timestamp
+                app1Pid2,                             // pid
+                app1Uid,                              // uid
+                app1Uid,                              // packageUid
+                app1DefiningUid,                      // definingUid
+                app1ProcessName,                      // processName
+                app1ConnectiongGroup,                 // connectionGroup
+                ApplicationExitInfo.REASON_EXIT_SELF, // reason
+                null,                                 // subReason
+                exitCode,                             // status
+                app1Pss2,                             // pss
+                app1Rss2,                             // rss
+                IMPORTANCE_SERVICE,                   // importance
+                null);                                // description
+
+        // Case 3: Create an instance of app1 with different user, and died because of SIGKILL
+        sleep(1);
+        final long now3 = System.currentTimeMillis();
+        int sigNum = OsConstants.SIGKILL;
+        app = makeProcessRecord(
+                app1PidUser2,                           // pid
+                app1UidUser2,                           // uid
+                app1UidUser2,                           // packageUid
+                null,                                   // definingUid
+                0,                                      // connectionGroup
+                PROCESS_STATE_BOUND_FOREGROUND_SERVICE, // procstate
+                app1Pss3,                               // pss
+                app1Rss3,                               // rss
+                app1ProcessName,                        // processName
+                app1PackageName);                       // packageName
+        doReturn(new Pair<Long, Object>(now3, Integer.valueOf(makeSignalStatus(sigNum))))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        updateExitInfo(app);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1PidUser2, 0, list);
+
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                // info
+                now3,                                // timestamp
+                app1PidUser2,                        // pid
+                app1UidUser2,                        // uid
+                app1UidUser2,                        // packageUid
+                null,                                // definingUid
+                app1ProcessName,                     // processName
+                0,                                   // connectionGroup
+                ApplicationExitInfo.REASON_SIGNALED, // reason
+                null,                                 // subReason
+                sigNum,                              // status
+                app1Pss3,                            // pss
+                app1Rss3,                            // rss
+                IMPORTANCE_FOREGROUND_SERVICE,       // importance
+                null);                               // description
+
+        // try go get all from app1UidUser2
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, 0, 0, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                // info
+                now3,                                // timestamp
+                app1PidUser2,                        // pid
+                app1UidUser2,                        // uid
+                app1UidUser2,                        // packageUid
+                null,                                // definingUid
+                app1ProcessName,                     // processName
+                0,                                   // connectionGroup
+                ApplicationExitInfo.REASON_SIGNALED, // reason
+                null,                                // subReason
+                sigNum,                              // status
+                app1Pss3,                            // pss
+                app1Rss3,                            // rss
+                IMPORTANCE_FOREGROUND_SERVICE,       // importance
+                null);                               // description
+
+        // Case 4: Create a process from another package with kill from lmkd
+        final int app2UidUser2 = 1010234;
+        final int app2PidUser2 = 12348;
+        final int app2Pss1 = 54321;
+        final int app2Rss1 = 65432;
+        final String app2ProcessName = "com.android.test.stub2:process";
+        final String app2PackageName = "com.android.test.stub2";
+
+        sleep(1);
+        final long now4 = System.currentTimeMillis();
+        doReturn(new Pair<Long, Object>(now4, Integer.valueOf(0)))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        doReturn(new Pair<Long, Object>(now4, null))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+                .remove(anyInt(), anyInt());
+
+        app = makeProcessRecord(
+                app2PidUser2,                // pid
+                app2UidUser2,                // uid
+                app2UidUser2,                // packageUid
+                null,                        // definingUid
+                0,                           // connectionGroup
+                PROCESS_STATE_CACHED_EMPTY,  // procstate
+                app2Pss1,                    // pss
+                app2Rss1,                    // rss
+                app2ProcessName,             // processName
+                app2PackageName);            // packageName
+        updateExitInfo(app);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app2PackageName, app2UidUser2, app2PidUser2, 0, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                     // info
+                now4,                                     // timestamp
+                app2PidUser2,                             // pid
+                app2UidUser2,                             // uid
+                app2UidUser2,                             // packageUid
+                null,                                     // definingUid
+                app2ProcessName,                          // processName
+                0,                                        // connectionGroup
+                ApplicationExitInfo.REASON_LOW_MEMORY,    // reason
+                null,                                     // subReason
+                0,                                        // status
+                app2Pss1,                                 // pss
+                app2Rss1,                                 // rss
+                IMPORTANCE_CACHED,                        // importance
+                null);                                    // description
+
+        // Verify to get all from User2 regarding app2
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app2UidUser2, 0, 0, list);
+        assertEquals(1, list.size());
+
+        // Case 5: App native crash
+        final int app3UidUser2 = 1010345;
+        final int app3PidUser2 = 12349;
+        final int app3ConnectiongGroup = 4;
+        final int app3Pss1 = 54320;
+        final int app3Rss1 = 65430;
+        final String app3ProcessName = "com.android.test.stub3:process";
+        final String app3PackageName = "com.android.test.stub3";
+        final String app3Description = "native crash";
+
+        sleep(1);
+        final long now5 = System.currentTimeMillis();
+        sigNum = OsConstants.SIGABRT;
+        doReturn(new Pair<Long, Object>(now5, Integer.valueOf(makeSignalStatus(sigNum))))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        doReturn(null)
+                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+                .remove(anyInt(), anyInt());
+        app = makeProcessRecord(
+                app3PidUser2,            // pid
+                app3UidUser2,            // uid
+                app3UidUser2,            // packageUid
+                null,                    // definingUid
+                app3ConnectiongGroup,    // connectionGroup
+                PROCESS_STATE_BOUND_TOP, // procstate
+                app3Pss1,                // pss
+                app3Rss1,                // rss
+                app3ProcessName,         // processName
+                app3PackageName);        // packageName
+        noteAppKill(app, ApplicationExitInfo.REASON_CRASH_NATIVE,
+                ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description);
+
+        updateExitInfo(app);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app3PackageName, app3UidUser2, app3PidUser2, 0, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                            // info
+                now5,                                            // timestamp
+                app3PidUser2,                                    // pid
+                app3UidUser2,                                    // uid
+                app3UidUser2,                                    // packageUid
+                null,                                            // definingUid
+                app3ProcessName,                                 // processName
+                app3ConnectiongGroup,                            // connectionGroup
+                ApplicationExitInfo.REASON_CRASH_NATIVE,         // reason
+                null,                                            // subReason
+                sigNum,                                          // status
+                app3Pss1,                                        // pss
+                app3Rss1,                                        // rss
+                IMPORTANCE_FOREGROUND,                           // importance
+                app3Description);                                // description
+
+        // Verify the most recent kills, sorted by timestamp
+        int maxNum = 3;
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app3UidUser2, 0, maxNum, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                            // info
+                now5,                                            // timestamp
+                app3PidUser2,                                    // pid
+                app3UidUser2,                                    // uid
+                app3UidUser2,                                    // packageUid
+                null,                                            // definingUid
+                app3ProcessName,                                 // processName
+                app3ConnectiongGroup,                            // connectionGroup
+                ApplicationExitInfo.REASON_CRASH_NATIVE,         // reason
+                null,                                            // subReason
+                sigNum,                                          // status
+                app3Pss1,                                        // pss
+                app3Rss1,                                        // rss
+                IMPORTANCE_FOREGROUND,                           // importance
+                app3Description);                                // description
+
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app2UidUser2, 0, maxNum, list);
+        assertEquals(1, list.size());
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                     // info
+                now4,                                     // timestamp
+                app2PidUser2,                             // pid
+                app2UidUser2,                             // uid
+                app2UidUser2,                             // packageUid
+                null,                                     // definingUid
+                app2ProcessName,                          // processName
+                0,                                        // connectionGroup
+                ApplicationExitInfo.REASON_LOW_MEMORY,    // reason
+                null,                                     // subReason
+                0,                                        // status
+                app2Pss1,                                 // pss
+                app2Rss1,                                 // rss
+                IMPORTANCE_CACHED,                        // importance
+                null);                                    // description
+
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app1UidUser2, 0, maxNum, list);
+        assertEquals(1, list.size());
+        info = list.get(0);
+
+        sigNum = OsConstants.SIGKILL;
+        verifyApplicationExitInfo(
+                info,                                // info
+                now3,                                // timestamp
+                app1PidUser2,                        // pid
+                app1UidUser2,                        // uid
+                app1UidUser2,                        // packageUid
+                null,                                // definingUid
+                app1ProcessName,                     // processName
+                0,                                   // connectionGroup
+                ApplicationExitInfo.REASON_SIGNALED, // reason
+                null,                                // subReason
+                sigNum,                              // status
+                app1Pss3,                            // pss
+                app1Rss3,                            // rss
+                IMPORTANCE_FOREGROUND_SERVICE,       // importance
+                null);                               // description
+
+        // Case 6: App Java crash
+        final int app3Uid = 10345;
+        final int app3IsolatedUid = 99001; // it's an isolated process
+        final int app3Pid = 12350;
+        final int app3Pss2 = 23232;
+        final int app3Rss2 = 32323;
+        final String app3Description2 = "force close";
+
+        sleep(1);
+        final long now6 = System.currentTimeMillis();
+        doReturn(null)
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        doReturn(null)
+                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+                .remove(anyInt(), anyInt());
+        app = makeProcessRecord(
+                app3Pid,                     // pid
+                app3IsolatedUid,             // uid
+                app3Uid,                     // packageUid
+                null,                        // definingUid
+                0,                           // connectionGroup
+                PROCESS_STATE_CACHED_EMPTY,  // procstate
+                app3Pss2,                    // pss
+                app3Rss2,                    // rss
+                app3ProcessName,             // processName
+                app3PackageName);            // packageName
+        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app3IsolatedUid, app3Uid);
+        noteAppKill(app, ApplicationExitInfo.REASON_CRASH,
+                ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description2);
+
+        assertEquals(app3Uid, mAppExitInfoTracker.mIsolatedUidRecords
+                .getUidByIsolatedUid(app3IsolatedUid).longValue());
+        updateExitInfo(app);
+        assertNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(app3IsolatedUid));
+
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app3PackageName, app3Uid, 0, 1, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                     // info
+                now6,                                     // timestamp
+                app3Pid,                                  // pid
+                app3IsolatedUid,                          // uid
+                app3Uid,                                  // packageUid
+                null,                                     // definingUid
+                app3ProcessName,                          // processName
+                0,                                        // connectionGroup
+                ApplicationExitInfo.REASON_CRASH,         // reason
+                null,                                     // subReason
+                0,                                        // status
+                app3Pss2,                                 // pss
+                app3Rss2,                                 // rss
+                IMPORTANCE_CACHED,                        // importance
+                app3Description2);                        // description
+
+        // Case 7: App1 is "uninstalled" from User2
+        mAppExitInfoTracker.onPackageRemoved(app1PackageName, app1UidUser2, false);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, 0, 0, list);
+        assertEquals(0, list.size());
+
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, 0, 0, list);
+        assertEquals(2, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                 // info
+                now2,                                 // timestamp
+                app1Pid2,                             // pid
+                app1Uid,                              // uid
+                app1Uid,                              // packageUid
+                app1DefiningUid,                      // definingUid
+                app1ProcessName,                      // processName
+                app1ConnectiongGroup,                 // connectionGroup
+                ApplicationExitInfo.REASON_EXIT_SELF, // reason
+                null,                                 // subReason
+                exitCode,                             // status
+                app1Pss2,                             // pss
+                app1Rss2,                             // rss
+                IMPORTANCE_SERVICE,                   // importance
+                null);                                // description
+
+        // Case 8: App1 gets "remove task"
+        final String app1Description = "remove task";
+
+        sleep(1);
+        final int app1IsolatedUidUser2 = 1099002; // isolated uid
+        final int app1Pss4 = 34343;
+        final int app1Rss4 = 43434;
+        final long now8 = System.currentTimeMillis();
+        sigNum = OsConstants.SIGKILL;
+        doReturn(new Pair<Long, Object>(now8, makeSignalStatus(sigNum)))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        doReturn(null)
+                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+                .remove(anyInt(), anyInt());
+        app = makeProcessRecord(
+                app1PidUser2,                 // pid
+                app1IsolatedUidUser2,         // uid
+                app1UidUser2,                 // packageUid
+                null,                         // definingUid
+                0,                            // connectionGroup
+                PROCESS_STATE_CACHED_EMPTY,   // procstate
+                app1Pss4,                     // pss
+                app1Rss4,                     // rss
+                app1ProcessName,              // processName
+                app1PackageName);             // packageName
+
+        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUidUser2, app1UidUser2);
+        noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                ApplicationExitInfo.SUBREASON_UNKNOWN, app1Description);
+
+        updateExitInfo(app);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1PidUser2, 1, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                     // info
+                now8,                                     // timestamp
+                app1PidUser2,                             // pid
+                app1IsolatedUidUser2,                     // uid
+                app1UidUser2,                             // packageUid
+                null,                                     // definingUid
+                app1ProcessName,                          // processName
+                0,                                        // connectionGroup
+                ApplicationExitInfo.REASON_OTHER,         // reason
+                ApplicationExitInfo.SUBREASON_UNKNOWN,    // subReason
+                0,                                        // status
+                app1Pss4,                                 // pss
+                app1Rss4,                                 // rss
+                IMPORTANCE_CACHED,                        // importance
+                app1Description);                         // description
+
+        // App1 gets "too many empty"
+        final String app1Description2 = "too many empty";
+        sleep(1);
+        final int app1Pid2User2 = 56565;
+        final int app1IsolatedUid2User2 = 1099003; // isolated uid
+        final int app1Pss5 = 34344;
+        final int app1Rss5 = 43435;
+        final long now9 = System.currentTimeMillis();
+        sigNum = OsConstants.SIGKILL;
+        doReturn(new Pair<Long, Object>(now9, makeSignalStatus(sigNum)))
+                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
+                .remove(anyInt(), anyInt());
+        doReturn(null)
+                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
+                .remove(anyInt(), anyInt());
+        app = makeProcessRecord(
+                app1Pid2User2,                // pid
+                app1IsolatedUid2User2,        // uid
+                app1UidUser2,                 // packageUid
+                null,                         // definingUid
+                0,                            // connectionGroup
+                PROCESS_STATE_CACHED_EMPTY,   // procstate
+                app1Pss5,                     // pss
+                app1Rss5,                     // rss
+                app1ProcessName,              // processName
+                app1PackageName);             // packageName
+
+        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUid2User2, app1UidUser2);
+        noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+                ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, app1Description2);
+
+        updateExitInfo(app);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1Pid2User2, 1, list);
+        assertEquals(1, list.size());
+
+        info = list.get(0);
+
+        verifyApplicationExitInfo(
+                info,                                         // info
+                now9,                                         // timestamp
+                app1Pid2User2,                                // pid
+                app1IsolatedUid2User2,                        // uid
+                app1UidUser2,                                 // packageUid
+                null,                                         // definingUid
+                app1ProcessName,                              // processName
+                0,                                            // connectionGroup
+                ApplicationExitInfo.REASON_OTHER,             // reason
+                ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, // subReason
+                0,                                            // status
+                app1Pss5,                                     // pss
+                app1Rss5,                                     // rss
+                IMPORTANCE_CACHED,                            // importance
+                app1Description2);                            // description
+
+
+        // Case 9: User2 gets removed
+        sleep(1);
+        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUidUser2, app1UidUser2);
+        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app3IsolatedUid, app3Uid);
+
+        mAppExitInfoTracker.onUserRemoved(UserHandle.getUserId(app1UidUser2));
+
+        assertNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(
+                app1IsolatedUidUser2));
+        assertNotNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(
+                app3IsolatedUid));
+        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(
+                app1IsolatedUidUser2, app1UidUser2);
+        mAppExitInfoTracker.mIsolatedUidRecords.removeAppUid(app1UidUser2, false);
+        assertNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(
+                app1IsolatedUidUser2));
+        mAppExitInfoTracker.mIsolatedUidRecords.removeAppUid(app3Uid, true);
+        assertNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(app3IsolatedUid));
+
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app1UidUser2, 0, 0, list);
+        assertEquals(0, list.size());
+
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
+        assertEquals(2, list.size());
+
+        info = list.get(0);
+
+        exitCode = 6;
+        verifyApplicationExitInfo(
+                info,                                 // info
+                now2,                                 // timestamp
+                app1Pid2,                             // pid
+                app1Uid,                              // uid
+                app1Uid,                              // packageUid
+                app1DefiningUid,                      // definingUid
+                app1ProcessName,                      // processName
+                app1ConnectiongGroup,                 // connectionGroup
+                ApplicationExitInfo.REASON_EXIT_SELF, // reason
+                null,                                 // subReason
+                exitCode,                             // status
+                app1Pss2,                             // pss
+                app1Rss2,                             // rss
+                IMPORTANCE_SERVICE,                   // importance
+                null);                                // description
+
+        info = list.get(1);
+        exitCode = 5;
+        verifyApplicationExitInfo(
+                info,                                 // info
+                now1,                                 // timestamp
+                app1Pid1,                             // pid
+                app1Uid,                              // uid
+                app1Uid,                              // packageUid
+                null,                                 // definingUid
+                app1ProcessName,                      // processName
+                0,                                    // connectionGroup
+                ApplicationExitInfo.REASON_EXIT_SELF, // reason
+                null,                                 // subReason
+                exitCode,                             // status
+                app1Pss1,                             // pss
+                app1Rss1,                             // rss
+                IMPORTANCE_CACHED,                    // importance
+                null);                                // description
+
+        // Case 10: Save the info and load them again
+        ArrayList<ApplicationExitInfo> original = new ArrayList<ApplicationExitInfo>();
+        mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, original);
+        assertTrue(original.size() > 0);
+
+        mAppExitInfoTracker.mProcExitInfoFile = new File(mContext.getFilesDir(),
+                AppExitInfoTracker.APP_EXIT_INFO_FILE);
+        mAppExitInfoTracker.persistProcessExitInfo();
+        assertTrue(mAppExitInfoTracker.mProcExitInfoFile.exists());
+
+        mAppExitInfoTracker.clearProcessExitInfo(false);
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
+        assertEquals(0, list.size());
+
+        mAppExitInfoTracker.loadExistingProcessExitInfo();
+        list.clear();
+        mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
+        assertEquals(original.size(), list.size());
+
+        for (int i = list.size() - 1; i >= 0; i--) {
+            assertTrue(list.get(i).equals(original.get(i)));
+        }
+    }
+
+    private static int makeExitStatus(int exitCode) {
+        return (exitCode << 8) & 0xff00;
+    }
+
+    private static int makeSignalStatus(int sigNum) {
+        return sigNum & 0x7f;
+    }
+
+    private void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    private ProcessRecord makeProcessRecord(int pid, int uid, int packageUid, Integer definingUid,
+            int connectionGroup, int procState, int pss, int rss,
+            String processName, String packageName) {
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = packageName;
+        ProcessRecord app = new ProcessRecord(mAms, ai, processName, uid);
+        app.pid = pid;
+        app.info.uid = packageUid;
+        if (definingUid != null) {
+            final String dummyPackageName = "com.android.test";
+            final String dummyClassName = ".Foo";
+            app.hostingRecord = HostingRecord.byAppZygote(new ComponentName(
+                    dummyPackageName, dummyClassName), "", definingUid);
+        }
+        app.connectionGroup = connectionGroup;
+        app.setProcState = procState;
+        app.lastMemInfo = spy(new Debug.MemoryInfo());
+        doReturn(pss).when(app.lastMemInfo).getTotalPss();
+        doReturn(rss).when(app.lastMemInfo).getTotalRss();
+        return app;
+    }
+
+    private void verifyApplicationExitInfo(ApplicationExitInfo info,
+            Long timestamp, Integer pid, Integer uid, Integer packageUid,
+            Integer definingUid, String processName, Integer connectionGroup,
+            Integer reason, Integer subReason, Integer status,
+            Integer pss, Integer rss, Integer importance, String description) {
+        assertNotNull(info);
+
+        if (timestamp != null) {
+            final long tolerance = 1000; // ms
+            assertTrue(timestamp - tolerance <= info.getTimestamp());
+            assertTrue(timestamp + tolerance >= info.getTimestamp());
+        }
+        if (pid != null) {
+            assertEquals(pid.intValue(), info.getPid());
+        }
+        if (uid != null) {
+            assertEquals(uid.intValue(), info.getRealUid());
+        }
+        if (packageUid != null) {
+            assertEquals(packageUid.intValue(), info.getPackageUid());
+        }
+        if (definingUid != null) {
+            assertEquals(definingUid.intValue(), info.getDefiningUid());
+        }
+        if (processName != null) {
+            assertTrue(TextUtils.equals(processName, info.getProcessName()));
+        }
+        if (connectionGroup != null) {
+            assertEquals(connectionGroup.intValue(), info.getConnectionGroup());
+        }
+        if (reason != null) {
+            assertEquals(reason.intValue(), info.getReason());
+        }
+        if (subReason != null) {
+            assertEquals(subReason.intValue(), info.getSubReason());
+        }
+        if (status != null) {
+            assertEquals(status.intValue(), info.getStatus());
+        }
+        if (pss != null) {
+            assertEquals(pss.intValue(), info.getPss());
+        }
+        if (rss != null) {
+            assertEquals(rss.intValue(), info.getRss());
+        }
+        if (importance != null) {
+            assertEquals(importance.intValue(), info.getImportance());
+        }
+        if (description != null) {
+            assertTrue(TextUtils.equals(description, info.getDescription()));
+        }
+    }
+
+    private class TestInjector extends Injector {
+        TestInjector(Context context) {
+            super(context);
+        }
+
+        @Override
+        public AppOpsService getAppOpsService(File file, Handler handler) {
+            return mAppOpsService;
+        }
+
+        @Override
+        public Handler getUiHandler(ActivityManagerService service) {
+            return mHandler;
+        }
+
+        @Override
+        public ProcessList getProcessList(ActivityManagerService service) {
+            return mProcessList;
+        }
+    }
+
+    static class ServiceThreadRule implements TestRule {
+
+        private ServiceThread mThread;
+
+        ServiceThread getThread() {
+            return mThread;
+        }
+
+        @Override
+        public Statement apply(Statement base, Description description) {
+            return new Statement() {
+                @Override
+                public void evaluate() throws Throwable {
+                    mThread = new ServiceThread("TestServiceThread",
+                            Process.THREAD_PRIORITY_DEFAULT, true /* allowIo */);
+                    mThread.start();
+                    try {
+                        base.evaluate();
+                    } finally {
+                        mThread.getThreadHandler().runWithScissors(mThread::quit, 0 /* timeout */);
+                    }
+                }
+            };
+        }
+    }
+}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 3a07a69..710e8df 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -61,6 +61,7 @@
     <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.STORAGE_INTERNAL" />
     <uses-permission android:name="android.permission.WATCH_APPOPS" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.SUSPEND_APPS"/>
@@ -71,6 +72,8 @@
     <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
     <uses-permission android:name="android.permission.HARDWARE_TEST"/>
     <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+    <uses-permission android:name="android.permission.DUMP" />
 
     <!-- Uses API introduced in O (26) -->
     <uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/servicestests/res/raw/comp_policies_primary.xml b/services/tests/servicestests/res/raw/comp_policies_primary.xml
index 1e1a0ef..d30f479 100644
--- a/services/tests/servicestests/res/raw/comp_policies_primary.xml
+++ b/services/tests/servicestests/res/raw/comp_policies_primary.xml
@@ -3,5 +3,6 @@
     <admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1">
         <policies flags="991"/>
         <password-history-length value="33" />
+        <user-restrictions no_bluetooth="true" />
     </admin>
 </policies>
diff --git a/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java b/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java
new file mode 100644
index 0000000..ed74947
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManagerInternal;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Looper;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.io.BufferedReader;
+import java.io.CharArrayWriter;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class PinnerServiceTest {
+    private static final int KEY_CAMERA = 0;
+    private static final int KEY_HOME = 1;
+    private static final int KEY_ASSISTANT = 2;
+
+    private static final long WAIT_FOR_PINNER_TIMEOUT = TimeUnit.SECONDS.toMillis(2);
+
+    @Rule
+    public TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getContext(), null);
+
+    private final ArraySet<String> mUpdatedPackages = new ArraySet<>();
+    private ResolveInfo mHomePackageResolveInfo;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
+        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+
+        ActivityTaskManagerInternal mockActivityTaskManagerInternal = mock(
+                ActivityTaskManagerInternal.class);
+        Intent homeIntent = getHomeIntent();
+
+        doReturn(homeIntent).when(mockActivityTaskManagerInternal).getHomeIntent();
+        LocalServices.addService(ActivityTaskManagerInternal.class,
+                mockActivityTaskManagerInternal);
+
+        ActivityManagerInternal mockActivityManagerInternal = mock(ActivityManagerInternal.class);
+        doReturn(true).when(mockActivityManagerInternal).isUidActive(anyInt());
+        LocalServices.addService(ActivityManagerInternal.class, mockActivityManagerInternal);
+
+        mContext = spy(mContext);
+
+        // Get HOME (Launcher) package
+        mHomePackageResolveInfo = mContext.getPackageManager().resolveActivityAsUser(homeIntent,
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 0);
+        mUpdatedPackages.add(mHomePackageResolveInfo.activityInfo.applicationInfo.packageName);
+    }
+
+    @After
+    public void tearDown() {
+        Mockito.framework().clearInlineMocks();
+    }
+
+    private Intent getHomeIntent() {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        return intent;
+    }
+
+    private void unpinAll(PinnerService pinnerService) throws Exception {
+        // unpin all packages
+        Method unpinAppMethod = PinnerService.class.getDeclaredMethod("unpinApp", int.class);
+        unpinAppMethod.setAccessible(true);
+        unpinAppMethod.invoke(pinnerService, KEY_HOME);
+        unpinAppMethod.invoke(pinnerService, KEY_CAMERA);
+        unpinAppMethod.invoke(pinnerService, KEY_ASSISTANT);
+    }
+
+    private void waitForPinnerService(PinnerService pinnerService)
+            throws NoSuchFieldException, IllegalAccessException {
+        // There's no notification/callback when pinning finished
+        // Block until pinner handler is done pinning and runs this empty runnable
+        Field pinnerHandlerField = PinnerService.class.getDeclaredField("mPinnerHandler");
+        pinnerHandlerField.setAccessible(true);
+        Handler pinnerServiceHandler = (Handler) pinnerHandlerField.get(pinnerService);
+        pinnerServiceHandler.runWithScissors(() -> {
+        }, WAIT_FOR_PINNER_TIMEOUT);
+    }
+
+    private ArraySet<Integer> getPinKeys(PinnerService pinnerService)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field pinKeysArrayField = PinnerService.class.getDeclaredField("mPinKeys");
+        pinKeysArrayField.setAccessible(true);
+        return (ArraySet<Integer>) pinKeysArrayField.get(pinnerService);
+    }
+
+    private ArrayMap<Integer, Object> getPinnedApps(PinnerService pinnerService)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field pinnedAppsField = PinnerService.class.getDeclaredField("mPinnedApps");
+        pinnedAppsField.setAccessible(true);
+        return (ArrayMap<Integer, Object>) pinnedAppsField.get(
+                pinnerService);
+    }
+
+    private String getPinnerServiceDump(PinnerService pinnerService) throws Exception {
+        Class<?> innerClass = Class.forName(PinnerService.class.getName() + "$BinderService");
+        Constructor<?> ctor = innerClass.getDeclaredConstructor(PinnerService.class);
+        ctor.setAccessible(true);
+        Binder innerInstance = (Binder) ctor.newInstance(pinnerService);
+        CharArrayWriter cw = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(cw, true);
+        Method dumpMethod = Binder.class.getDeclaredMethod("dump", FileDescriptor.class,
+                PrintWriter.class, String[].class);
+        dumpMethod.setAccessible(true);
+        dumpMethod.invoke(innerInstance, null, pw, null);
+        return cw.toString();
+    }
+
+    private int getPinnedSize(PinnerService pinnerService) throws Exception {
+        final String totalSizeToken = "Total size: ";
+        String dumpOutput = getPinnerServiceDump(pinnerService);
+        BufferedReader bufReader = new BufferedReader(new StringReader(dumpOutput));
+        Optional<Integer> size = bufReader.lines().filter(s -> s.contains(totalSizeToken))
+                .map(s -> Integer.valueOf(s.substring(totalSizeToken.length()))).findAny();
+        return size.orElse(-1);
+    }
+
+    @Test
+    public void testPinHomeApp() throws Exception {
+        // Enable HOME app pinning
+        Resources res = mock(Resources.class);
+        doReturn(true).when(res).getBoolean(com.android.internal.R.bool.config_pinnerHomeApp);
+        when(mContext.getResources()).thenReturn(res);
+        PinnerService pinnerService = new PinnerService(mContext);
+
+        ArraySet<Integer> pinKeys = getPinKeys(pinnerService);
+        assertThat(pinKeys.valueAt(0)).isEqualTo(KEY_HOME);
+
+        pinnerService.update(mUpdatedPackages, true);
+
+        waitForPinnerService(pinnerService);
+
+        ArrayMap<Integer, Object> pinnedApps = getPinnedApps(pinnerService);
+        assertThat(pinnedApps.get(KEY_HOME)).isNotNull();
+
+        // Check if dump() reports total pinned bytes
+        int totalPinnedSizeBytes = getPinnedSize(pinnerService);
+        assertThat(totalPinnedSizeBytes).isGreaterThan(0);
+
+        // Make sure pinned files are unmapped
+        unpinAll(pinnerService);
+    }
+
+    @Test
+    public void testPinHomeAppOnBootCompleted() throws Exception {
+        // Enable HOME app pinning
+        Resources res = mock(Resources.class);
+        doReturn(true).when(res).getBoolean(com.android.internal.R.bool.config_pinnerHomeApp);
+        when(mContext.getResources()).thenReturn(res);
+        PinnerService pinnerService = new PinnerService(mContext);
+
+        ArraySet<Integer> pinKeys = getPinKeys(pinnerService);
+        assertThat(pinKeys.valueAt(0)).isEqualTo(KEY_HOME);
+
+        pinnerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+
+        waitForPinnerService(pinnerService);
+
+        ArrayMap<Integer, Object> pinnedApps = getPinnedApps(pinnerService);
+        assertThat(pinnedApps.get(KEY_HOME)).isNotNull();
+
+        // Check if dump() reports total pinned bytes
+        int totalPinnedSizeBytes = getPinnedSize(pinnerService);
+        assertThat(totalPinnedSizeBytes).isGreaterThan(0);
+
+        // Make sure pinned files are unmapped
+        unpinAll(pinnerService);
+    }
+
+    @Test
+    public void testNothingToPin() throws Exception {
+        // No package enabled for pinning
+        Resources res = mock(Resources.class);
+        when(mContext.getResources()).thenReturn(res);
+        PinnerService pinnerService = new PinnerService(mContext);
+
+        ArraySet<Integer> pinKeys = getPinKeys(pinnerService);
+        assertThat(pinKeys).isEmpty();
+
+        pinnerService.update(mUpdatedPackages, true);
+
+        waitForPinnerService(pinnerService);
+
+        ArrayMap<Integer, Object> pinnedApps = getPinnedApps(pinnerService);
+        assertThat(pinnedApps).isEmpty();
+
+        // Check if dump() reports total pinned bytes
+        int totalPinnedSizeBytes = getPinnedSize(pinnerService);
+        assertThat(totalPinnedSizeBytes).isEqualTo(0);
+
+        // Make sure pinned files are unmapped
+        unpinAll(pinnerService);
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index e1e9b7e..cf10559 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -495,6 +495,13 @@
     }
 
     @Test
+    public void getSystemActions() {
+        List<AccessibilityNodeInfo.AccessibilityAction> actions =
+                mServiceConnection.getSystemActions();
+        verify(mMockSystemActionPerformer).getSystemActions();
+    }
+
+    @Test
     public void isFingerprintGestureDetectionAvailable_hasFingerPrintSupport_returnTrue() {
         when(mMockFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable())
                 .thenReturn(true);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
index 193f540..87b5658 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
@@ -80,7 +80,7 @@
     // The expected order of EventStreamTransformations.
     private final Class[] mExpectedEventHandlerTypes =
             {KeyboardInterceptor.class, MotionEventInjector.class,
-                    MagnificationGestureHandler.class, TouchExplorer.class,
+                    FullScreenMagnificationGestureHandler.class, TouchExplorer.class,
                     AutoclickController.class, AccessibilityInputFilter.class};
 
     private MagnificationController mMockMagnificationController;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 75239db..ec928fb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -16,16 +16,28 @@
 
 package com.android.server.accessibility;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.Manifest;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.IAccessibilityServiceClient;
 import android.app.PendingIntent;
 import android.app.RemoteAction;
+import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Icon;
+import android.os.IBinder;
+import android.os.UserHandle;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -34,6 +46,7 @@
 
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
+import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -59,6 +72,14 @@
     private static final AccessibilityAction NEW_ACCESSIBILITY_ACTION =
             new AccessibilityAction(ACTION_ID, LABEL);
 
+    static final ComponentName COMPONENT_NAME = new ComponentName(
+            "com.android.server.accessibility", "AccessibilityManagerServiceTest");
+    static final int SERVICE_ID = 42;
+
+    @Mock private Context mMockContext;
+    @Mock private AccessibilityServiceInfo mMockServiceInfo;
+    @Mock private ResolveInfo mMockResolveInfo;
+    @Mock private AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport;
     @Mock private PackageManager mMockPackageManager;
     @Mock private WindowManagerInternal mMockWindowManagerService;
     @Mock private AccessibilitySecurityPolicy mMockSecurityPolicy;
@@ -66,7 +87,12 @@
     @Mock private AccessibilityWindowManager mMockA11yWindowManager;
     @Mock private AccessibilityDisplayListener mMockA11yDisplayListener;
     @Mock private ActivityTaskManagerInternal mMockActivityTaskManagerInternal;
+    @Mock private IBinder mMockBinder;
+    @Mock private IAccessibilityServiceClient mMockServiceClient;
+    private AccessibilityUserState mUserState;
 
+    private MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
+    private AccessibilityServiceConnection mAccessibilityServiceConnection;
     private AccessibilityManagerService mA11yms;
 
     @Override
@@ -74,9 +100,11 @@
         MockitoAnnotations.initMocks(this);
         LocalServices.removeServiceForTest(WindowManagerInternal.class);
         LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
-        LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerService);
+        LocalServices.addService(
+                WindowManagerInternal.class, mMockWindowManagerService);
         LocalServices.addService(
                 ActivityTaskManagerInternal.class, mMockActivityTaskManagerInternal);
+
         mA11yms = new AccessibilityManagerService(
             InstrumentationRegistry.getContext(),
             mMockPackageManager,
@@ -86,6 +114,35 @@
             mMockA11yDisplayListener);
     }
 
+    private void setupAccessibilityServiceConnection() {
+        when(mMockContext.getSystemService(Context.DISPLAY_SERVICE)).thenReturn(
+                InstrumentationRegistry.getContext().getSystemService(
+                        Context.DISPLAY_SERVICE));
+        mUserState = new AccessibilityUserState(UserHandle.USER_SYSTEM, mMockContext, mA11yms);
+
+        when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
+        mMockResolveInfo.serviceInfo = mock(ServiceInfo.class);
+        mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
+
+        when(mMockBinder.queryLocalInterface(any())).thenReturn(mMockServiceClient);
+        mAccessibilityServiceConnection = new AccessibilityServiceConnection(
+                mUserState,
+                mMockContext,
+                COMPONENT_NAME,
+                mMockServiceInfo,
+                SERVICE_ID,
+                mHandler,
+                new Object(),
+                mMockSecurityPolicy,
+                mMockSystemSupport,
+                mMockWindowManagerService,
+                mMockSystemActionPerformer,
+                mMockA11yWindowManager,
+                mMockActivityTaskManagerInternal);
+        mAccessibilityServiceConnection.bindLocked();
+        mAccessibilityServiceConnection.onServiceConnected(COMPONENT_NAME, mMockBinder);
+    }
+
     @SmallTest
     public void testRegisterSystemActionWithoutPermission() throws Exception {
         doThrow(SecurityException.class).when(mMockSecurityPolicy).enforceCallingPermission(
@@ -125,4 +182,11 @@
         mA11yms.unregisterSystemAction(ACTION_ID);
         verify(mMockSystemActionPerformer).unregisterSystemAction(ACTION_ID);
     }
+
+    @SmallTest
+    public void testOnSystemActionsChanged() throws Exception {
+        setupAccessibilityServiceConnection();
+        mA11yms.notifySystemActionsChangedLocked(mUserState);
+        verify(mMockServiceClient).onSystemActionsChanged();
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java
similarity index 96%
rename from services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
rename to services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java
index de7d77d..2007d4f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java
@@ -59,7 +59,7 @@
 import java.util.function.IntConsumer;
 
 /**
- * Tests the state transitions of {@link MagnificationGestureHandler}
+ * Tests the state transitions of {@link FullScreenMagnificationGestureHandler}
  *
  * Here's a dot graph describing the transitions being tested:
  * {@code
@@ -87,7 +87,7 @@
  * }
  */
 @RunWith(AndroidJUnit4.class)
-public class MagnificationGestureHandlerTest {
+public class FullScreenMagnificationGestureHandlerTest {
 
     public static final int STATE_IDLE = 1;
     public static final int STATE_ZOOMED = 2;
@@ -113,7 +113,7 @@
     MagnificationController mMagnificationController;
 
     private OffsettableClock mClock;
-    private MagnificationGestureHandler mMgh;
+    private FullScreenMagnificationGestureHandler mMgh;
     private TestHandler mHandler;
 
     private long mLastDownTime = Integer.MIN_VALUE;
@@ -154,16 +154,17 @@
     }
 
     @NonNull
-    private MagnificationGestureHandler newInstance(boolean detectTripleTap,
+    private FullScreenMagnificationGestureHandler newInstance(boolean detectTripleTap,
             boolean detectShortcutTrigger) {
-        MagnificationGestureHandler h = new MagnificationGestureHandler(
+        FullScreenMagnificationGestureHandler h = new FullScreenMagnificationGestureHandler(
                 mContext, mMagnificationController,
                 detectTripleTap, detectShortcutTrigger, DISPLAY_0);
         mHandler = new TestHandler(h.mDetectingState, mClock) {
             @Override
             protected String messageToString(Message m) {
                 return DebugUtils.valueToString(
-                        MagnificationGestureHandler.DetectingState.class, "MESSAGE_", m.what);
+                        FullScreenMagnificationGestureHandler.DetectingState.class, "MESSAGE_",
+                        m.what);
             }
         };
         h.mDetectingState.mHandler = mHandler;
@@ -541,7 +542,8 @@
     }
 
     private static String stateToString(int state) {
-        return DebugUtils.valueToString(MagnificationGestureHandlerTest.class, "STATE_", state);
+        return DebugUtils.valueToString(FullScreenMagnificationGestureHandlerTest.class, "STATE_",
+                state);
     }
 
     private void tap() {
@@ -591,7 +593,7 @@
 
     private MotionEvent moveEvent(float x, float y) {
         return fromTouchscreen(
-        	    MotionEvent.obtain(mLastDownTime, mClock.now(), ACTION_MOVE, x, y, 0));
+                MotionEvent.obtain(mLastDownTime, mClock.now(), ACTION_MOVE, x, y, 0));
     }
 
     private MotionEvent downEvent() {
@@ -638,7 +640,7 @@
             /* action */ action,
             /* pointerCount */ 2,
             /* pointerProperties */ new MotionEvent.PointerProperties[] {
-                        defPointerProperties, pointerProperties },
+                    defPointerProperties, pointerProperties},
             /* pointerCoords */ new MotionEvent.PointerCoords[] { defPointerCoords, pointerCoords },
             /* metaState */ 0,
             /* buttonState */ 0,
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java
index 4195679..34ade81 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java
@@ -101,7 +101,9 @@
         IllegalStateException e = expectThrows(
                 IllegalStateException.class,
                 () -> impl.setSchema(
-                        /*callingUid=*/Integer.MAX_VALUE, SchemaProto.getDefaultInstance()));
+                        /*callingUid=*/Integer.MAX_VALUE,
+                        SchemaProto.getDefaultInstance(),
+                        /*forceOverride=*/false));
         assertThat(e).hasMessageThat().contains("Failed to look up package name");
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
index ecd07bd..b14291b 100644
--- a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
@@ -188,7 +188,7 @@
     }
 
     @Test
-    public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_rejectOverride()
+    public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_allowOverride()
             throws Exception {
         CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext)
                         .addEnabledChangeWithId(1).build();
@@ -203,11 +203,11 @@
                 overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
 
         assertThat(allowedState)
-                .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1));
+                .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1));
     }
 
     @Test
-    public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_rejectOverride()
+    public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_allowOverride()
             throws Exception {
         CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext)
                         .addDisabledChangeWithId(1).build();
@@ -221,7 +221,7 @@
                 overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
 
         assertThat(allowedState)
-                .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1));
+                .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index 46b8371..9574a08 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -371,10 +371,16 @@
         poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID);
 
         runAsCaller(poContext, dpms, dpm -> {
-            // Check that DO policy is now set on parent instance.
-            assertEquals(33, dpm.getParentProfileInstance(admin1).getPasswordHistoryLength(admin1));
-            // And NOT set on profile instance.
-            assertEquals(0, dpm.getPasswordHistoryLength(admin1));
+            assertEquals("Password history policy wasn't migrated to PO parent instance",
+                    33, dpm.getParentProfileInstance(admin1).getPasswordHistoryLength(admin1));
+            assertEquals("Password history policy was put into non-parent PO instance",
+                    0, dpm.getPasswordHistoryLength(admin1));
+
+            assertTrue("User restriction wasn't migrated to PO parent instance",
+                    dpm.getParentProfileInstance(admin1).getUserRestrictions(admin1)
+                            .containsKey(UserManager.DISALLOW_BLUETOOTH));
+            assertFalse("User restriction was put into non-parent PO instance",
+                    dpm.getUserRestrictions(admin1).containsKey(UserManager.DISALLOW_BLUETOOTH));
 
             // TODO(b/143516163): verify more policies.
         });
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 632a2c1..43e9570 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3723,6 +3723,39 @@
         assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
     }
 
+    public void testSetLockdownAdminConfiguredNetworksWithDO() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        dpm.setLockdownAdminConfiguredNetworks(admin1, true);
+        verify(getServices().settings).settingsGlobalPutInt(
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 1);
+
+        dpm.setLockdownAdminConfiguredNetworks(admin1, false);
+        verify(getServices().settings).settingsGlobalPutInt(
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0);
+    }
+
+    public void testSetLockdownAdminConfiguredNetworksWithPO() throws Exception {
+        setupProfileOwner();
+        assertExpectException(SecurityException.class, null,
+                () -> dpm.setLockdownAdminConfiguredNetworks(admin1, false));
+        verify(getServices().settings, never()).settingsGlobalPutInt(
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0);
+    }
+
+    public void testSetLockdownAdminConfiguredNetworksWithPOOfOrganizationOwnedDevice()
+            throws Exception {
+        setupProfileOwner();
+        configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+        dpm.setLockdownAdminConfiguredNetworks(admin1, true);
+        verify(getServices().settings).settingsGlobalPutInt(
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 1);
+
+        dpm.setLockdownAdminConfiguredNetworks(admin1, false);
+        verify(getServices().settings).settingsGlobalPutInt(
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0);
+    }
+
     public void testSetSystemSettingFailWithNonWhitelistedSettings() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
diff --git a/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java b/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java
index 63bccfa..9ecba59 100644
--- a/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java
@@ -22,6 +22,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.test.AndroidTestCase;
+
 import com.android.server.job.MockPriorityJobService.TestEnvironment;
 import com.android.server.job.MockPriorityJobService.TestEnvironment.Event;
 
@@ -35,6 +36,11 @@
     static ComponentName kJobServiceComponent;
     JobScheduler mJobScheduler;
 
+    // The system overrides the test app priority to be a minimum of FOREGROUND_SERVICE. We can
+    // bypass that override by using a priority of at least bound foreground service.
+    private static final int HIGH_PRIORITY = JobInfo.PRIORITY_BOUND_FOREGROUND_SERVICE + 1;
+    private static final int LOW_PRIORITY = JobInfo.PRIORITY_BOUND_FOREGROUND_SERVICE;
+
     @Override
     public void setUp() throws Exception {
         super.setUp();
@@ -51,32 +57,25 @@
     }
 
     public void testLowerPriorityJobPreempted() throws Exception {
-        JobInfo job1 = new JobInfo.Builder(111, kJobServiceComponent)
-                .setPriority(1)
-                .setOverrideDeadline(7000L)
+        for (int i = 0; i < JobSchedulerService.MAX_JOB_CONTEXTS_COUNT; ++i) {
+            JobInfo job = new JobInfo.Builder(100 + i, kJobServiceComponent)
+                    .setPriority(LOW_PRIORITY)
+                    .setOverrideDeadline(0)
+                    .build();
+            mJobScheduler.schedule(job);
+        }
+        final int higherPriorityJobId = 100 + JobSchedulerService.MAX_JOB_CONTEXTS_COUNT;
+        JobInfo jobHigher = new JobInfo.Builder(higherPriorityJobId, kJobServiceComponent)
+                .setPriority(HIGH_PRIORITY)
+                .setMinimumLatency(2000)
+                .setOverrideDeadline(4000)
                 .build();
-        JobInfo job2 = new JobInfo.Builder(222, kJobServiceComponent)
-                .setPriority(1)
-                .setOverrideDeadline(7000L)
-                .build();
-        JobInfo job3 = new JobInfo.Builder(333, kJobServiceComponent)
-                .setPriority(1)
-                .setOverrideDeadline(7000L)
-                .build();
-        JobInfo job4 = new JobInfo.Builder(444, kJobServiceComponent)
-                .setPriority(2)
-                .setMinimumLatency(2000L)
-                .setOverrideDeadline(7000L)
-                .build();
-        mJobScheduler.schedule(job1);
-        mJobScheduler.schedule(job2);
-        mJobScheduler.schedule(job3);
-        mJobScheduler.schedule(job4);
-        Thread.sleep(10000);  // Wait for job 4 to preempt one of the lower priority jobs
+        mJobScheduler.schedule(jobHigher);
+        Thread.sleep(10000);  // Wait for jobHigher to preempt one of the lower priority jobs
 
-        Event job4Execution = new Event(TestEnvironment.EVENT_START_JOB, 444);
+        Event jobHigherExecution = new Event(TestEnvironment.EVENT_START_JOB, higherPriorityJobId);
         ArrayList<Event> executedEvents = kTestEnvironment.getExecutedEvents();
-        boolean wasJob4Executed = executedEvents.contains(job4Execution);
+        boolean wasJobHigherExecuted = executedEvents.contains(jobHigherExecution);
         boolean wasSomeJobPreempted = false;
         for (Event event: executedEvents) {
             if (event.event == TestEnvironment.EVENT_PREEMPT_JOB) {
@@ -85,35 +84,28 @@
             }
         }
         assertTrue("No job was preempted.", wasSomeJobPreempted);
-        assertTrue("Lower priority jobs were not preempted.",  wasJob4Executed);
+        assertTrue("Lower priority jobs were not preempted.", wasJobHigherExecuted);
     }
 
     public void testHigherPriorityJobNotPreempted() throws Exception {
-        JobInfo job1 = new JobInfo.Builder(111, kJobServiceComponent)
-                .setPriority(2)
-                .setOverrideDeadline(7000L)
+        for (int i = 0; i < JobSchedulerService.MAX_JOB_CONTEXTS_COUNT; ++i) {
+            JobInfo job = new JobInfo.Builder(100 + i, kJobServiceComponent)
+                    .setPriority(HIGH_PRIORITY)
+                    .setOverrideDeadline(0)
+                    .build();
+            mJobScheduler.schedule(job);
+        }
+        final int lowerPriorityJobId = 100 + JobSchedulerService.MAX_JOB_CONTEXTS_COUNT;
+        JobInfo jobLower = new JobInfo.Builder(lowerPriorityJobId, kJobServiceComponent)
+                .setPriority(LOW_PRIORITY)
+                .setMinimumLatency(2000)
+                .setOverrideDeadline(3000)
                 .build();
-        JobInfo job2 = new JobInfo.Builder(222, kJobServiceComponent)
-                .setPriority(2)
-                .setOverrideDeadline(7000L)
-                .build();
-        JobInfo job3 = new JobInfo.Builder(333, kJobServiceComponent)
-                .setPriority(2)
-                .setOverrideDeadline(7000L)
-                .build();
-        JobInfo job4 = new JobInfo.Builder(444, kJobServiceComponent)
-                .setPriority(1)
-                .setMinimumLatency(2000L)
-                .setOverrideDeadline(7000L)
-                .build();
-        mJobScheduler.schedule(job1);
-        mJobScheduler.schedule(job2);
-        mJobScheduler.schedule(job3);
-        mJobScheduler.schedule(job4);
-        Thread.sleep(10000);  // Wait for job 4 to preempt one of the higher priority jobs
+        mJobScheduler.schedule(jobLower);
+        Thread.sleep(10000);
 
-        Event job4Execution = new Event(TestEnvironment.EVENT_START_JOB, 444);
-        boolean wasJob4Executed = kTestEnvironment.getExecutedEvents().contains(job4Execution);
-        assertFalse("Higher priority job was preempted.", wasJob4Executed);
+        Event jobLowerExecution = new Event(TestEnvironment.EVENT_START_JOB, lowerPriorityJobId);
+        boolean wasLowerExecuted = kTestEnvironment.getExecutedEvents().contains(jobLowerExecution);
+        assertFalse("Higher priority job was preempted.", wasLowerExecuted);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index a3d15dd..1b5c56a 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -230,6 +230,18 @@
             }
         }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());
 
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                mStorageManager.clearUserKeyAuth((int) args[0] /* userId */,
+                        (int) args[1] /* serialNumber */,
+                        (byte[]) args[2] /* token */,
+                        (byte[]) args[3] /* secret */);
+                return null;
+            }
+        }).when(sm).clearUserKeyAuth(anyInt(), anyInt(), any(), any());
+
         doAnswer(
                 new Answer<Void>() {
             @Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/FakeStorageManager.java b/services/tests/servicestests/src/com/android/server/locksettings/FakeStorageManager.java
index 1ae1fa6..102bac1 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/FakeStorageManager.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/FakeStorageManager.java
@@ -36,6 +36,15 @@
         getUserAuth(userId).add(new Pair<>(token, secret));
     }
 
+    public void clearUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) {
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (token == null && secret == null) {
+            return;
+        }
+        auths.remove(new Pair<>(token, secret));
+        auths.add(new Pair<>(null, null));
+    }
+
     public void fixateNewestUserKeyAuth(int userId) {
         ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
         Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
diff --git a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
index e18ff61..68f60b4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
@@ -13,14 +13,17 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
+import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.IApplicationThread;
+import android.app.admin.DevicePolicyManagerInternal;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
@@ -76,6 +79,10 @@
     private ActivityManagerInternal mActivityManagerInternal;
     @Mock
     private ActivityTaskManagerInternal mActivityTaskManagerInternal;
+    @Mock
+    private IPackageManager mIPackageManager;
+    @Mock
+    private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
 
     private TestInjector mTestInjector;
     private ActivityInfo mActivityInfo;
@@ -578,5 +585,26 @@
         public ActivityTaskManagerInternal getActivityTaskManagerInternal() {
             return mActivityTaskManagerInternal;
         }
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return mIPackageManager;
+        }
+
+        @Override
+        public DevicePolicyManagerInternal getDevicePolicyManagerInternal() {
+            return mDevicePolicyManagerInternal;
+        }
+
+        @Override
+        public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+            mContext.sendBroadcastAsUser(intent, user);
+        }
+
+        @Override
+        public int checkComponentPermission(
+                String permission, int uid, int owningUid, boolean exported) {
+            return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
index e375aef..9eaf8b6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
@@ -23,7 +23,9 @@
 
 import android.content.pm.UserInfo;
 import android.os.Looper;
+import android.os.ServiceSpecificException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.UserManagerInternal;
 
 import androidx.test.InstrumentationRegistry;
@@ -31,11 +33,13 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.LocalServices;
+import com.android.server.storage.DeviceStorageMonitorInternal;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 import java.util.List;
 
@@ -243,6 +247,65 @@
                         true /* allow remove */));
     }
 
+    @Test
+    public void testCreateProfileForUser_lowStorageException() {
+        DeviceStorageMonitorInternal dsmMock = Mockito.mock(DeviceStorageMonitorInternal.class);
+        Mockito.when(dsmMock.isMemoryLow()).thenReturn(true);
+        LocalServices.addService(DeviceStorageMonitorInternal.class, dsmMock);
+
+        try {
+            mUserManagerService.createProfileForUserWithThrow("user2", USER_TYPE_PROFILE_MANAGED, 0,
+                    UserHandle.USER_SYSTEM, null);
+        } catch (ServiceSpecificException e) {
+            assertEquals(UserManager.USER_OPERATION_ERROR_LOW_STORAGE,
+                    UserManager.UserOperationException.from(e).getUserOperationResult());
+        } finally {
+            LocalServices.removeServiceForTest(DeviceStorageMonitorInternal.class);
+        }
+    }
+
+    @Test
+    public void testCreateProfileForUser_unknownParentUser() {
+        DeviceStorageMonitorInternal dsmMock = Mockito.mock(DeviceStorageMonitorInternal.class);
+        Mockito.when(dsmMock.isMemoryLow()).thenReturn(false);
+        LocalServices.addService(DeviceStorageMonitorInternal.class, dsmMock);
+
+        try {
+            final int badParentUserId = 1234;
+            mUserManagerService.createProfileForUserWithThrow("profile", USER_TYPE_PROFILE_MANAGED,
+                    0, badParentUserId, null);
+        } catch (ServiceSpecificException e) {
+            assertEquals(UserManager.USER_OPERATION_ERROR_UNKNOWN,
+                    UserManager.UserOperationException.from(e).getUserOperationResult());
+        } finally {
+            LocalServices.removeServiceForTest(DeviceStorageMonitorInternal.class);
+        }
+    }
+
+    @Test
+    public void testCreateManagedProfileForUser_maxManagedUsersException() {
+        DeviceStorageMonitorInternal dsmMock = Mockito.mock(DeviceStorageMonitorInternal.class);
+        Mockito.when(dsmMock.isMemoryLow()).thenReturn(false);
+        LocalServices.addService(DeviceStorageMonitorInternal.class, dsmMock);
+
+        UserManagerService userManagerServiceSpy = Mockito.spy(mUserManagerService);
+        Mockito.doReturn(false).when(userManagerServiceSpy).canAddMoreManagedProfiles(
+                Mockito.anyInt(), Mockito.anyBoolean());
+
+        Mockito.doReturn(false).when(userManagerServiceSpy).canAddMoreProfilesToUser(
+                Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean());
+
+        try {
+            userManagerServiceSpy.createProfileForUserWithThrow("profile",
+                    USER_TYPE_PROFILE_MANAGED, 0, UserHandle.USER_SYSTEM, null);
+        } catch (ServiceSpecificException e) {
+            assertEquals(UserManager.USER_OPERATION_ERROR_MAX_USERS,
+                    UserManager.UserOperationException.from(e).getUserOperationResult());
+        } finally {
+            LocalServices.removeServiceForTest(DeviceStorageMonitorInternal.class);
+        }
+    }
+
     private void removeUsers() {
         List<UserInfo> users = mUserManagerService.getUsers(/* excludeDying */ false);
         for (UserInfo user: users) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 77376f0..2469cec 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -39,6 +39,7 @@
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Slog;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -69,8 +70,10 @@
 
     // Packages which are used during tests.
     private static final String[] PACKAGES = new String[] {
-            "com.android.egg"
+            "com.android.egg",
+            "com.google.android.webview"
     };
+    private static final String TAG = UserManagerTest.class.getSimpleName();
 
     private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
 
@@ -333,6 +336,9 @@
         assertThat(userInfo).isNotNull();
         final int userId = userInfo.id;
 
+        UserManager userManagerForUser = (UserManager) mContext.createPackageContextAsUser(
+                "android", 0, asHandle(userId)).getSystemService(Context.USER_SERVICE);
+
         assertThat(mUserManager.hasBadge(userId)).isEqualTo(userTypeDetails.hasBadge());
         assertThat(mUserManager.getUserIconBadgeResId(userId))
                 .isEqualTo(userTypeDetails.getIconBadge());
@@ -340,9 +346,11 @@
                 .isEqualTo(userTypeDetails.getBadgePlain());
         assertThat(mUserManager.getUserBadgeNoBackgroundResId(userId))
                 .isEqualTo(userTypeDetails.getBadgeNoBackground());
-        assertThat(mUserManager.isProfile(userId)).isEqualTo(userTypeDetails.isProfile());
         assertThat(mUserManager.isUserOfType(asHandle(userId), userTypeDetails.getName()))
                 .isTrue();
+        assertThat(userManagerForUser.isProfile()).isEqualTo(userTypeDetails.isProfile());
+        assertThat(userManagerForUser.isUserOfType(asHandle(userId), userTypeDetails.getName()))
+                .isTrue();
 
         final int badgeIndex = userInfo.profileBadge;
         assertThat(mUserManager.getUserBadgeColor(userId)).isEqualTo(
@@ -351,7 +359,7 @@
                 Resources.getSystem().getString(userTypeDetails.getBadgeLabel(badgeIndex), "Test"));
     }
 
-    // Make sure only one managed profile can be created
+    // Make sure only max managed profiles can be created
     @MediumTest
     @Test
     public void testAddManagedProfile() throws Exception {
@@ -384,6 +392,11 @@
                 UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
         // Verify that the packagesToVerify are installed by default.
         for (String pkg : PACKAGES) {
+            if (!mPackageManager.isPackageAvailable(pkg)) {
+                Slog.w(TAG, "Package is not available " + pkg);
+                continue;
+            }
+
             assertWithMessage("Package should be installed in managed profile: %s", pkg)
                     .that(isPackageInstalledForUser(pkg, userInfo1.id)).isTrue();
         }
@@ -393,6 +406,11 @@
                 UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId, PACKAGES);
         // Verify that the packagesToVerify are not installed by default.
         for (String pkg : PACKAGES) {
+            if (!mPackageManager.isPackageAvailable(pkg)) {
+                Slog.w(TAG, "Package is not available " + pkg);
+                continue;
+            }
+
             assertWithMessage(
                     "Package should not be installed in managed profile when disallowed: %s", pkg)
                             .that(isPackageInstalledForUser(pkg, userInfo2.id)).isFalse();
@@ -410,12 +428,22 @@
                 UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId, PACKAGES);
         // Verify that the packagesToVerify are not installed by default.
         for (String pkg : PACKAGES) {
+            if (!mPackageManager.isPackageAvailable(pkg)) {
+                Slog.w(TAG, "Package is not available " + pkg);
+                continue;
+            }
+
             assertWithMessage("Pkg should not be installed in managed profile when disallowed: %s",
                     pkg).that(isPackageInstalledForUser(pkg, userInfo.id)).isFalse();
         }
 
         // Verify that the disallowed packages during profile creation can be installed now.
         for (String pkg : PACKAGES) {
+            if (!mPackageManager.isPackageAvailable(pkg)) {
+                Slog.w(TAG, "Package is not available " + pkg);
+                continue;
+            }
+
             assertWithMessage("Package could not be installed: %s", pkg)
                     .that(mPackageManager.installExistingPackageAsUser(pkg, userInfo.id))
                     .isEqualTo(PackageManager.INSTALL_SUCCEEDED);
@@ -774,6 +802,78 @@
         assertThat(found).isTrue();
     }
 
+    @Test
+    public void testCreateProfile_withContextUserId() throws Exception {
+        final int primaryUserId = mUserManager.getPrimaryUser().id;
+
+        UserInfo userProfile = createProfileForUser("Managed 1",
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+        assertThat(userProfile).isNotNull();
+
+        UserManager um = (UserManager) mContext.createPackageContextAsUser(
+                "android", 0, mUserManager.getPrimaryUser().getUserHandle())
+                .getSystemService(Context.USER_SERVICE);
+
+        List<UserHandle> profiles = um.getUserProfiles(false);
+        assertThat(profiles.size()).isEqualTo(2);
+        assertThat(profiles.get(0).equals(userProfile.getUserHandle())
+                || profiles.get(1).equals(userProfile.getUserHandle())).isTrue();
+    }
+
+    @Test
+    public void testSetUserName_withContextUserId() throws Exception {
+        final int primaryUserId = mUserManager.getPrimaryUser().id;
+
+        UserInfo userInfo1 = createProfileForUser("Managed 1",
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+        assertThat(userInfo1).isNotNull();
+
+        UserManager um = (UserManager) mContext.createPackageContextAsUser(
+                "android", 0, userInfo1.getUserHandle())
+                .getSystemService(Context.USER_SERVICE);
+
+        final String newName = "Managed_user 1";
+        um.setUserName(newName);
+
+        UserInfo userInfo = mUserManager.getUserInfo(userInfo1.id);
+        assertThat(userInfo.name).isEqualTo(newName);
+
+        // get user name from getUserName using context.getUserId
+        assertThat(um.getUserName()).isEqualTo(newName);
+    }
+
+    @Test
+    public void testGetUserName_withContextUserId() throws Exception {
+        final String userName = "User 2";
+        UserInfo user2 = createUser(userName, 0);
+        assertThat(user2).isNotNull();
+
+        UserManager um = (UserManager) mContext.createPackageContextAsUser(
+                "android", 0, user2.getUserHandle())
+                .getSystemService(Context.USER_SERVICE);
+
+        assertThat(um.getUserName()).isEqualTo(userName);
+    }
+
+    @Test
+    public void testGetUserIcon_withContextUserId() throws Exception {
+        final int primaryUserId = mUserManager.getPrimaryUser().id;
+
+        UserInfo userInfo1 = createProfileForUser("Managed 1",
+                UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+        assertThat(userInfo1).isNotNull();
+
+        UserManager um = (UserManager) mContext.createPackageContextAsUser(
+                "android", 0, userInfo1.getUserHandle())
+                .getSystemService(Context.USER_SERVICE);
+
+        final String newName = "Managed_user 1";
+        um.setUserName(newName);
+
+        UserInfo userInfo = mUserManager.getUserInfo(userInfo1.id);
+        assertThat(userInfo.name).isEqualTo(newName);
+    }
+
     private boolean isPackageInstalledForUser(String packageName, int userId) {
         try {
             return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
index f5af3ec..d16c232a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
@@ -18,6 +18,7 @@
 
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
@@ -30,6 +31,7 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 
 import com.android.server.UiServiceTestCase;
@@ -52,6 +54,7 @@
     public void testExtractsUpdatedChannel() {
         NotificationChannelExtractor extractor = new NotificationChannelExtractor();
         extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
 
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
         final Notification.Builder builder = new Notification.Builder(getContext())
@@ -71,4 +74,62 @@
         assertNull(extractor.process(r));
         assertEquals(updatedChannel, r.getChannel());
     }
+
+    @Test
+    public void testInvalidShortcutFlagEnabled_looksUpCorrectChannel() {
+        Settings.Global.putString(
+                mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
+
+        NotificationChannelExtractor extractor = new NotificationChannelExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        final Notification.Builder builder = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setStyle(new Notification.MessagingStyle("name"))
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        Notification n = builder.build();
+        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "tag", 0,
+                0, n, UserHandle.ALL, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+
+        NotificationChannel updatedChannel =
+                new NotificationChannel("a", "", IMPORTANCE_HIGH);
+        when(mConfig.getConversationNotificationChannel(
+                any(), anyInt(), eq("a"), eq(r.sbn.getShortcutId(mContext)), eq(true), eq(false)))
+                .thenReturn(updatedChannel);
+
+        assertNull(extractor.process(r));
+        assertEquals(updatedChannel, r.getChannel());
+    }
+
+    @Test
+    public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() {
+        Settings.Global.putString(
+                mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+
+        NotificationChannelExtractor extractor = new NotificationChannelExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        final Notification.Builder builder = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setStyle(new Notification.MessagingStyle("name"))
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        Notification n = builder.build();
+        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "tag", 0,
+                0, n, UserHandle.ALL, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+
+        NotificationChannel updatedChannel =
+                new NotificationChannel("a", "", IMPORTANCE_HIGH);
+        when(mConfig.getConversationNotificationChannel(
+                any(), anyInt(), eq("a"), eq(null), eq(true), eq(false)))
+                .thenReturn(updatedChannel);
+
+        assertNull(extractor.process(r));
+        assertEquals(updatedChannel, r.getChannel());
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index 9ad6986..5b5ad87 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -186,6 +186,20 @@
     }
 
     @Test
+    public void testAddNotification_newestFirst() {
+        HistoricalNotification n = getHistoricalNotification(1);
+        HistoricalNotification n2 = getHistoricalNotification(2);
+
+        mDataBase.addNotification(n);
+
+        // second add should not trigger another write
+        mDataBase.addNotification(n2);
+
+        assertThat(mDataBase.mBuffer.getNotificationsToWrite().get(0)).isEqualTo(n2);
+        assertThat(mDataBase.mBuffer.getNotificationsToWrite().get(1)).isEqualTo(n);
+    }
+
+    @Test
     public void testReadNotificationHistory_readsAllFiles() throws Exception {
         for (long i = 10; i >= 5; i--) {
             AtomicFile af = mock(AtomicFile.class);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java
index 3b6a4bd..b5eb1bf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryManagerTest.java
@@ -40,8 +40,8 @@
 
 import com.android.server.UiServiceTestCase;
 
+import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -115,6 +115,11 @@
         mHistoryManager.onBootPhaseAppsCanStart();
     }
 
+    @After
+    public void tearDown() {
+        mHistoryManager.onDestroy();
+    }
+
     @Test
     public void testOnUserUnlocked() {
         assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
@@ -126,22 +131,52 @@
     }
 
     @Test
-    @Ignore("b/147012298")
     public void testOnUserUnlocked_historyDisabled() {
+        // create a history
+        mHistoryManager.onUserUnlocked(USER_SYSTEM);
+        assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue();
+        // lock user
+        mHistoryManager.onUserStopped(USER_SYSTEM);
+
+        // turn off history
         Settings.Secure.putIntForUser(getContext().getContentResolver(),
                 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
         mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
-        assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
-        assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
 
+        // unlock user, verify that history is disabled
         mHistoryManager.onUserUnlocked(USER_SYSTEM);
 
         assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isFalse();
-        assertThat(mHistoryManager.isUserUnlocked(USER_SYSTEM)).isFalse();
         verify(mDb, times(1)).disableHistory();
     }
 
     @Test
+    public void testOnUserUnlocked_historyDisabledThenEnabled() {
+        // create a history
+        mHistoryManager.onUserUnlocked(USER_SYSTEM);
+        assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue();
+
+        // lock user
+        mHistoryManager.onUserStopped(USER_SYSTEM);
+
+        // turn off history
+        Settings.Secure.putIntForUser(getContext().getContentResolver(),
+                Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
+        mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
+
+        // turn on history
+        Settings.Secure.putIntForUser(getContext().getContentResolver(),
+                Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 1, USER_SYSTEM);
+        mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
+
+        // unlock user, verify that history is NOT disabled
+        mHistoryManager.onUserUnlocked(USER_SYSTEM);
+
+        assertThat(mHistoryManager.doesHistoryExistForUser(USER_SYSTEM)).isTrue();
+        verify(mDb, never()).disableHistory();
+    }
+
+    @Test
     public void testOnUserUnlocked_cleansUpRemovedPackages() {
         String pkg = "pkg";
         mHistoryManager.onPackageRemoved(USER_SYSTEM, pkg);
@@ -223,6 +258,8 @@
 
     @Test
     public void testOnPackageRemoved_historyDisabled() {
+        mHistoryManager.onUserUnlocked(USER_SYSTEM);
+
         Settings.Secure.putIntForUser(getContext().getContentResolver(),
                 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, USER_SYSTEM);
         mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
@@ -427,6 +464,8 @@
     public void testIsHistoryEnabled() {
         assertThat(mHistoryManager.isHistoryEnabled(USER_SYSTEM)).isTrue();
 
+        mHistoryManager.onUserUnlocked(USER_SYSTEM);
+
         Settings.Secure.putIntForUser(getContext().getContentResolver(),
                 Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0,  USER_SYSTEM);
         mHistoryManager.mSettingsObserver.update(null, USER_SYSTEM);
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 2ac4642..c6c64c9 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5834,7 +5834,8 @@
         mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(
                 orig)));
 
-        mBinderService.createConversationNotificationChannelForPackage(PKG, mUid, orig, "friend");
+        mBinderService.createConversationNotificationChannelForPackage(
+                PKG, mUid, "key", orig, "friend");
 
         NotificationChannel friendChannel = mBinderService.getConversationNotificationChannel(
                 PKG, 0, PKG, original.getId(), false, "friend");
@@ -5869,9 +5870,10 @@
         String conversationId = "friend";
 
         mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, NotificationChannel.CREATOR.createFromParcel(msgParcel), conversationId);
+                PKG, mUid, "key", NotificationChannel.CREATOR.createFromParcel(msgParcel),
+                conversationId);
         mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, NotificationChannel.CREATOR.createFromParcel(callParcel),
+                PKG, mUid, "key", NotificationChannel.CREATOR.createFromParcel(callParcel),
                 conversationId);
 
         NotificationChannel messagesChild = mBinderService.getConversationNotificationChannel(
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 6f16574..c1c74da 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -22,6 +22,7 @@
 import static android.app.NotificationManager.IMPORTANCE_MAX;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.util.FeatureFlagUtils.NOTIF_CONVO_BYPASS_SHORTCUT_REQ;
 
 import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
 
@@ -2858,4 +2859,84 @@
             // good
         }
     }
+
+    @Test
+    public void testPlaceholderConversationId_flagOn() throws Exception {
+        Settings.Global.putString(
+                mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+                + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+    }
+
+    @Test
+    public void testPlaceholderConversationId_flagOff() throws Exception {
+        Settings.Global.putString(
+                mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+                + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"foo:placeholder_id\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+    }
+
+    @Test
+    public void testNormalConversationId_flagOff() throws Exception {
+        Settings.Global.putString(
+                mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+                + "<channel id=\"id\" name=\"hi\" importance=\"3\" conv_id=\"other\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+    }
+
+    @Test
+    public void testNoConversationId_flagOff() throws Exception {
+        Settings.Global.putString(
+                mContext.getContentResolver(), NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "false");
+        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+                + "<channel id=\"id\" name=\"hi\" importance=\"3\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertNotNull(mHelper.getNotificationChannel(PKG_O, UID_O, "id", true));
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index ad63d07..c60ca48 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -123,13 +123,13 @@
     @Test
     public void testStackCleanupOnClearingTask() {
         mActivity.onParentChanged(null /*newParent*/, mActivity.getTask());
-        verify(mStack, times(1)).onActivityRemovedFromStack(any());
+        verify(mStack, times(1)).cleanUpActivityReferences(any());
     }
 
     @Test
     public void testStackCleanupOnActivityRemoval() {
         mTask.removeChild(mActivity);
-        verify(mStack, times(1)).onActivityRemovedFromStack(any());
+        verify(mStack, times(1)).cleanUpActivityReferences(any());
     }
 
     @Test
@@ -141,10 +141,9 @@
 
     @Test
     public void testNoCleanupMovingActivityInSameStack() {
-        final Task newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack)
-                .build();
+        final Task newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
         mActivity.reparent(newTask, 0, null /*reason*/);
-        verify(mStack, times(0)).onActivityRemovedFromStack(any());
+        verify(mStack, times(0)).cleanUpActivityReferences(any());
     }
 
     @Test
@@ -490,7 +489,7 @@
 
         final ActivityStack stack = new StackBuilder(mRootWindowContainer).build();
         try {
-            doReturn(false).when(stack).isStackTranslucent(any());
+            doReturn(false).when(stack).isTranslucent(any());
             assertFalse(mStack.shouldBeVisible(null /* starting */));
 
             mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
@@ -613,8 +612,7 @@
         // Sending 'null' for saved state can only happen due to timeout, so previously stored saved
         // states should not be overridden.
         mActivity.setState(STOPPING, "test");
-        mActivity.activityStopped(null /* savedState */, null /* persistentSavedState */,
-                "desc");
+        mActivity.activityStopped(null /* savedState */, null /* persistentSavedState */, "desc");
         assertTrue(mActivity.hasSavedState());
         assertEquals(savedState, mActivity.getSavedState());
         assertEquals(persistentSavedState, mActivity.getPersistentSavedState());
@@ -1013,7 +1011,9 @@
     public void testDestroyIfPossible_lastActivityAboveEmptyHomeStack() {
         // Empty the home stack.
         final ActivityStack homeStack = mActivity.getDisplay().getHomeStack();
-        homeStack.forAllTasks((t) -> { homeStack.removeChild(t, "test"); });
+        homeStack.forAllTasks((t) -> {
+            homeStack.removeChild(t, "test");
+        }, true /* traverseTopToBottom */, homeStack);
         mActivity.finishing = true;
         doReturn(false).when(mRootWindowContainer).resumeFocusedStacksTopActivities();
         spyOn(mStack);
@@ -1037,7 +1037,9 @@
     public void testCompleteFinishing_lastActivityAboveEmptyHomeStack() {
         // Empty the home stack.
         final ActivityStack homeStack = mActivity.getDisplay().getHomeStack();
-        homeStack.forAllTasks((t) -> { homeStack.removeChild(t, "test"); });
+        homeStack.forAllTasks((t) -> {
+            homeStack.removeChild(t, "test");
+        }, true /* traverseTopToBottom */, homeStack);
         mActivity.finishing = true;
         spyOn(mStack);
 
@@ -1143,7 +1145,7 @@
         assertNull(mActivity.app);
         assertNull(mActivity.getTask());
         assertEquals(0, task.getChildCount());
-        assertNull(task.getStack());
+        assertEquals(task.getStack(), task);
         assertEquals(0, stack.getChildCount());
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index a5157fe9..393d8b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -313,13 +313,13 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
         // should be visible since it is always on-top.
-        doReturn(false).when(fullscreenStack).isStackTranslucent(any());
+        doReturn(false).when(fullscreenStack).isTranslucent(any());
         assertFalse(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
         assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
 
         // Home stack should be visible behind a translucent fullscreen stack.
-        doReturn(true).when(fullscreenStack).isStackTranslucent(any());
+        doReturn(true).when(fullscreenStack).isTranslucent(any());
         assertTrue(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
     }
@@ -338,8 +338,8 @@
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
         // Home stack shouldn't be visible if both halves of split-screen are opaque.
-        doReturn(false).when(splitScreenPrimary).isStackTranslucent(any());
-        doReturn(false).when(splitScreenSecondary).isStackTranslucent(any());
+        doReturn(false).when(splitScreenPrimary).isTranslucent(any());
+        doReturn(false).when(splitScreenSecondary).isTranslucent(any());
         assertFalse(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
@@ -350,7 +350,7 @@
                 splitScreenSecondary.getVisibility(null /* starting */));
 
         // Home stack should be visible if one of the halves of split-screen is translucent.
-        doReturn(true).when(splitScreenPrimary).isStackTranslucent(any());
+        doReturn(true).when(splitScreenPrimary).isTranslucent(any());
         assertTrue(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
@@ -366,7 +366,7 @@
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         // First split-screen secondary shouldn't be visible behind another opaque split-split
         // secondary.
-        doReturn(false).when(splitScreenSecondary2).isStackTranslucent(any());
+        doReturn(false).when(splitScreenSecondary2).isTranslucent(any());
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
         assertEquals(STACK_VISIBILITY_INVISIBLE,
@@ -376,7 +376,7 @@
 
         // First split-screen secondary should be visible behind another translucent split-screen
         // secondary.
-        doReturn(true).when(splitScreenSecondary2).isStackTranslucent(any());
+        doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
         assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
@@ -388,7 +388,7 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
 
         // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
-        doReturn(false).when(assistantStack).isStackTranslucent(any());
+        doReturn(false).when(assistantStack).isTranslucent(any());
         assertTrue(assistantStack.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
@@ -403,7 +403,7 @@
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
         // Split-screen stacks should be visible behind a translucent fullscreen stack.
-        doReturn(true).when(assistantStack).isStackTranslucent(any());
+        doReturn(true).when(assistantStack).isTranslucent(any());
         assertTrue(assistantStack.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
@@ -418,9 +418,9 @@
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
         // Assistant stack shouldn't be visible behind translucent split-screen stack
-        doReturn(false).when(assistantStack).isStackTranslucent(any());
-        doReturn(true).when(splitScreenPrimary).isStackTranslucent(any());
-        doReturn(true).when(splitScreenSecondary2).isStackTranslucent(any());
+        doReturn(false).when(assistantStack).isTranslucent(any());
+        doReturn(true).when(splitScreenPrimary).isTranslucent(any());
+        doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
         splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
         splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
         assertFalse(assistantStack.shouldBeVisible(null /* starting */));
@@ -555,7 +555,7 @@
         final ActivityStack translucentStack = createStackForShouldBeVisibleTest(
                 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
-        doReturn(true).when(translucentStack).isStackTranslucent(any());
+        doReturn(true).when(translucentStack).isTranslucent(any());
 
         assertTrue(homeStack.shouldBeVisible(null /* starting */));
         assertTrue(translucentStack.shouldBeVisible(null /* starting */));
@@ -603,8 +603,8 @@
         final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack).isStackTranslucent(any());
+        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(false).when(fullscreenStack).isTranslucent(any());
 
         // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
         int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
@@ -622,8 +622,8 @@
         final ActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isStackTranslucent(any());
-        doReturn(true).when(fullscreenStack).isStackTranslucent(any());
+        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(true).when(fullscreenStack).isTranslucent(any());
 
         // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
         int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
@@ -641,8 +641,8 @@
         final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
-        doReturn(false).when(homeStack).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack).isStackTranslucent(any());
+        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(false).when(fullscreenStack).isTranslucent(any());
 
         // Ensure we don't move the home stack if it is already on top
         int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
@@ -666,9 +666,9 @@
         final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
-        doReturn(false).when(homeStack).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack1).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack2).isStackTranslucent(any());
+        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(false).when(fullscreenStack1).isTranslucent(any());
+        doReturn(false).when(fullscreenStack2).isTranslucent(any());
 
         // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
         // pinned stack
@@ -691,9 +691,9 @@
                 mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
                 true /* onTop */);
 
-        doReturn(false).when(homeStack).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack1).isStackTranslucent(any());
-        doReturn(true).when(fullscreenStack2).isStackTranslucent(any());
+        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(false).when(fullscreenStack1).isTranslucent(any());
+        doReturn(true).when(fullscreenStack2).isTranslucent(any());
 
         // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
         // stack
@@ -715,9 +715,9 @@
         final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
-        doReturn(false).when(homeStack).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack1).isStackTranslucent(any());
-        doReturn(false).when(fullscreenStack2).isStackTranslucent(any());
+        doReturn(false).when(homeStack).isTranslucent(any());
+        doReturn(false).when(fullscreenStack1).isTranslucent(any());
+        doReturn(false).when(fullscreenStack2).isTranslucent(any());
 
         // Ensure we don't move the home stack behind itself
         int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
@@ -810,9 +810,9 @@
         final ActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
 
-        doReturn(false).when(splitScreenPrimary).isStackTranslucent(any());
-        doReturn(false).when(splitScreenSecondary).isStackTranslucent(any());
-        doReturn(false).when(assistantStack).isStackTranslucent(any());
+        doReturn(false).when(splitScreenPrimary).isTranslucent(any());
+        doReturn(false).when(splitScreenSecondary).isTranslucent(any());
+        doReturn(false).when(assistantStack).isTranslucent(any());
 
         assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
         assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
@@ -829,7 +829,7 @@
             boolean translucent) {
         final ActivityStack stack = createStackForShouldBeVisibleTest(mDefaultDisplay,
                 windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        doReturn(translucent).when(stack).isStackTranslucent(any());
+        doReturn(translucent).when(stack).isTranslucent(any());
         return stack;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 4beede9..eb84d0a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -375,7 +375,7 @@
             intent.setComponent(mComponent);
             intent.setFlags(mFlags);
 
-            final Task task = new Task(mSupervisor.mService, mTaskId, aInfo,
+            final Task task = new ActivityStack(mSupervisor.mService, mTaskId, aInfo,
                     intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
                     null /*taskDescription*/, mStack);
             spyOn(task);
@@ -398,6 +398,8 @@
         private int mActivityType = ACTIVITY_TYPE_STANDARD;
         private boolean mOnTop = true;
         private boolean mCreateActivity = true;
+        private ActivityInfo mInfo;
+        private Intent mIntent;
 
         StackBuilder(RootWindowContainer root) {
             mRootWindowContainer = root;
@@ -434,13 +436,22 @@
             return this;
         }
 
+        StackBuilder setActivityInfo(ActivityInfo info) {
+            mInfo = info;
+            return this;
+        }
+
+        StackBuilder setIntent(Intent intent) {
+            mIntent = intent;
+            return this;
+        }
+
         ActivityStack build() {
             final int stackId = mStackId >= 0 ? mStackId : mDisplay.getNextStackId();
-            final ActivityStack stack;
+            final ActivityStack stack = mDisplay.createStackUnchecked(mWindowingMode,
+                    mActivityType, stackId, mOnTop, mInfo, mIntent);
             final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor;
 
-            stack = mDisplay.createStackUnchecked(mWindowingMode, mActivityType, stackId, mOnTop);
-
             if (mCreateActivity) {
                 new ActivityBuilder(supervisor.mService)
                         .setCreateTask(true)
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index e8f7849..7344fa4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -27,8 +27,11 @@
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.when;
 
+import android.annotation.Nullable;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.SurfaceControl;
@@ -111,8 +114,12 @@
     private static class SurfaceAnimatorStarterImpl implements Dimmer.SurfaceAnimatorStarter {
         @Override
         public void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
-                AnimationAdapter anim, boolean hidden) {
-            surfaceAnimator.mAnimationFinishedCallback.run();
+                AnimationAdapter anim, boolean hidden,
+                @Nullable Runnable animationFinishedCallback) {
+            surfaceAnimator.mStaticAnimationFinishedCallback.run();
+            if (animationFinishedCallback != null) {
+                animationFinishedCallback.run();
+            }
         }
     }
 
@@ -216,7 +223,8 @@
 
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mSurfaceAnimatorStarter).startAnimation(any(SurfaceAnimator.class), any(
-                SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean());
+                SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean(),
+                isNull());
         verify(mHost.getPendingTransaction()).remove(dimLayer);
     }
 
@@ -273,7 +281,8 @@
         mDimmer.resetDimStates();
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mSurfaceAnimatorStarter, never()).startAnimation(any(SurfaceAnimator.class), any(
-                SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean());
+                SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean(),
+                isNull());
         verify(mTransaction).remove(dimLayer);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f2ba97c..1637370 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -39,6 +39,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -139,6 +140,7 @@
                 mChildAppWindowAbove,
                 mDockedDividerWindow,
                 mStatusBarWindow,
+                mNotificationShadeWindow,
                 mNavBarWindow,
                 mImeWindow,
                 mImeDialogWindow));
@@ -161,6 +163,7 @@
                 mImeDialogWindow,
                 mDockedDividerWindow,
                 mStatusBarWindow,
+                mNotificationShadeWindow,
                 mNavBarWindow));
     }
 
@@ -177,6 +180,7 @@
                 mImeDialogWindow,
                 mDockedDividerWindow,
                 mStatusBarWindow,
+                mNotificationShadeWindow,
                 mNavBarWindow));
     }
 
@@ -193,6 +197,24 @@
                 mStatusBarWindow,
                 mImeWindow,
                 mImeDialogWindow,
+                mNotificationShadeWindow,
+                mNavBarWindow));
+    }
+
+    @Test
+    public void testForAllWindows_WithNotificationShadeImeTarget() throws Exception {
+        mDisplayContent.mInputMethodTarget = mNotificationShadeWindow;
+
+        assertForAllWindowsOrder(Arrays.asList(
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNotificationShadeWindow,
+                mImeWindow,
+                mImeDialogWindow,
                 mNavBarWindow));
     }
 
@@ -211,6 +233,7 @@
                 mDockedDividerWindow,
                 voiceInteractionWindow,
                 mStatusBarWindow,
+                mNotificationShadeWindow,
                 mNavBarWindow,
                 mImeWindow,
                 mImeDialogWindow));
@@ -585,7 +608,7 @@
         final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
         window.mActivityRecord.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
-        final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
+        final WindowState keyguard = createWindow(null, TYPE_NOTIFICATION_SHADE , dc, "keyguard");
         keyguard.mHasSurface = true;
         keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index df34c7c..c3bead7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -22,13 +22,16 @@
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -118,11 +121,11 @@
 
     @Test
     public void testControlsForDispatch_keyguard() {
-        addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |= PRIVATE_FLAG_KEYGUARD;
+        addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade");
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
+        mockKeyguardShowing();
 
         final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
-
         // The app must not control the top bar.
         assertNotNull(controls);
         assertEquals(1, controls.length);
@@ -130,9 +133,9 @@
 
     // TODO: adjust this test if we pretend to the app that it's still able to control it.
     @Test
-    public void testControlsForDispatch_forceStatusBarVisibleTransparent() {
-        addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |=
-                PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
+    public void testControlsForDispatch_forceStatusBarVisible() {
+        addWindow(TYPE_STATUS_BAR, "topBar").mAttrs.privateFlags |=
+                PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
         final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -144,7 +147,7 @@
 
     @Test
     public void testControlsForDispatch_statusBarForceShowNavigation() {
-        addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |=
+        addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |=
                 PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
         addWindow(TYPE_NAVIGATION_BAR, "navBar");
 
@@ -257,4 +260,10 @@
         mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
         return mDisplayContent.getInsetsStateController().getControlsForDispatch(win);
     }
+
+    private void mockKeyguardShowing() {
+        final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+        spyOn(displayPolicy);
+        doReturn(true).when(displayPolicy).isKeyguardShowing();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 894890a..277bc41 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
@@ -85,9 +86,12 @@
     public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() {
         final WindowState statusBar =
                 createWindow(null, TYPE_STATUS_BAR, "statusBar", FAKE_CALLING_UID);
+        final WindowState notificationShade = createWindow(null, TYPE_NOTIFICATION_SHADE,
+                "notificationShade", FAKE_CALLING_UID);
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
 
         assertFalse(statusBar.isVisibleNow());
+        assertFalse(notificationShade.isVisibleNow());
         assertFalse(app.isVisibleNow());
         assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 9562fa4..fa0485c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -152,6 +152,8 @@
     @Test
     public void testReturnsToHomeStack() throws Exception {
         final Task task = createTask(1);
+        spyOn(task);
+        doReturn(true).when(task).hasChild();
         assertFalse(task.returnsToHomeStack());
         task.intent = null;
         assertFalse(task.returnsToHomeStack());
@@ -906,7 +908,7 @@
     }
 
     private Task createTask(int taskId) {
-        return new Task(mService, taskId, new Intent(), null, null, null,
+        return new ActivityStack(mService, taskId, new Intent(), null, null, null,
                 ActivityBuilder.getDefaultComponent(), null, false, false, false, 0, 10050, null,
                 0, false, null, 0, 0, 0, 0, 0, null, 0, false, false, false, 0,
                 0, null /*ActivityInfo*/, null /*_voiceSession*/, null /*_voiceInteractor*/,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index b4f5751..6e4be88 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -115,7 +115,7 @@
         // Remove stack and check if its child is also removed.
         stack.removeImmediately();
         assertNull(stack.getDisplayContent());
-        assertNull(task.getStack());
+        assertNull(task.getParent());
     }
 
     @Test
@@ -131,7 +131,7 @@
         assertEquals(0, stack.getChildCount());
         assertNull(stack.getDisplayContent());
         assertNull(task.getDisplayContent());
-        assertNull(task.getStack());
+        assertNull(task.getParent());
     }
 
     @Test
@@ -140,6 +140,7 @@
         final Task task = createTaskInStack(stack, 0 /* userId */);
 
         // Stack removal is deferred if one of its child is animating.
+        doReturn(true).when(stack).hasWindowsAlive();
         doReturn(true).when(task).isAnimating(TRANSITION | CHILDREN);
 
         stack.removeIfPossible();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 08ee0eb..9f45044 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -91,7 +91,7 @@
 
     @Override
     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
-        return attrs.type == TYPE_STATUS_BAR;
+        return attrs.type == TYPE_NOTIFICATION_SHADE;
     }
 
     @Override
@@ -263,6 +263,11 @@
     }
 
     @Override
+    public boolean isKeyguardShowing() {
+        return mKeyguardShowingAndNotOccluded;
+    }
+
+    @Override
     public boolean isKeyguardShowingAndNotOccluded() {
         return mKeyguardShowingAndNotOccluded;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index d3cd3cb..05d048d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -829,12 +829,15 @@
         wc.getDisplayContent().mAppTransition.overridePendingAppTransitionRemote(adapter);
         spyOn(wc);
         doReturn(true).when(wc).okToAnimate();
+        final Runnable onAnimationFinishedCallback = mock(Runnable.class);
 
         // Make sure animating state is as expected after applied animation.
-        assertTrue(wc.applyAnimation(null, TRANSIT_TASK_OPEN, true, false));
+        assertTrue(wc.applyAnimation(null, TRANSIT_TASK_OPEN, true, false,
+                onAnimationFinishedCallback));
         assertEquals(wc.getTopMostActivity(), act);
         assertTrue(wc.isAnimating());
         assertTrue(act.isAnimating(PARENTS));
+        verify(onAnimationFinishedCallback, times(0)).run();
 
         // Make sure animation finish callback will be received and reset animating state after
         // animation finish.
@@ -843,6 +846,7 @@
         verify(wc).onAnimationFinished();
         assertFalse(wc.isAnimating());
         assertFalse(act.isAnimating(PARENTS));
+        verify(onAnimationFinishedCallback, times(1)).run();
     }
 
     /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 7e248f8..6d0b54f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -545,7 +545,7 @@
         final WindowState startingWindow = createWindow(null /* parent */,
                 TYPE_APPLICATION_STARTING, startingApp.mToken, "starting");
         startingApp.mActivityRecord.startingWindow = startingWindow;
-        final WindowState keyguardHostWindow = mStatusBarWindow;
+        final WindowState keyguardHostWindow = mNotificationShadeWindow;
         final WindowState allDrawnApp = mAppWindow;
         allDrawnApp.mActivityRecord.allDrawn = true;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 31a7f24..20eab5a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -31,6 +31,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
@@ -76,6 +77,7 @@
     WindowState mImeWindow;
     WindowState mImeDialogWindow;
     WindowState mStatusBarWindow;
+    WindowState mNotificationShadeWindow;
     WindowState mDockedDividerWindow;
     WindowState mNavBarWindow;
     WindowState mAppWindow;
@@ -119,6 +121,8 @@
                 mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
                         "mImeDialogWindow");
                 mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
+                mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
+                        "mNotificationShadeWindow");
                 mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
                 mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
                         "mDockedDividerWindow");
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java
new file mode 100644
index 0000000..9cda084
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static android.graphics.Bitmap.Config.ARGB_8888;
+
+import static org.junit.Assert.assertEquals;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.ColorSpace;
+import android.graphics.GraphicBuffer;
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.view.Surface;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class RotationAnimationUtilsTest {
+
+    private static final int BITMAP_HEIGHT = 100;
+    private static final int BITMAP_WIDTH = 100;
+    private static final int POINT_WIDTH = 1000;
+    private static final int POINT_HEIGHT = 2000;
+
+    private ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
+    private Matrix mMatrix;
+
+    @Before
+    public void setup() {
+        mMatrix = new Matrix();
+    }
+
+    @Test
+    public void blackLuma() {
+        Bitmap swBitmap = createBitmap(0);
+        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
+        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
+        assertEquals(0, borderLuma, 0);
+    }
+
+    @Test
+    public void whiteLuma() {
+        Bitmap swBitmap = createBitmap(1);
+        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
+        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
+        assertEquals(1, borderLuma, 0);
+    }
+
+    @Test
+    public void whiteImageBlackBorderLuma() {
+        Bitmap swBitmap = createBitmap(1);
+        setBorderLuma(swBitmap, 0);
+        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
+        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
+        assertEquals(0, borderLuma, 0);
+    }
+
+    @Test
+    public void blackImageWhiteBorderLuma() {
+        Bitmap swBitmap = createBitmap(0);
+        setBorderLuma(swBitmap, 1);
+        GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
+        float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
+        assertEquals(1, borderLuma, 0);
+    }
+
+    @Test
+    public void rotate_0_bottomRight() {
+        RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_0,
+                POINT_WIDTH, POINT_HEIGHT, mMatrix);
+        PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT);
+        assertEquals(POINT_WIDTH, newPoints.x, 0);
+        assertEquals(POINT_HEIGHT, newPoints.y, 0);
+    }
+
+    @Test
+    public void rotate_90_bottomRight() {
+        RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_90,
+                POINT_WIDTH, POINT_HEIGHT, mMatrix);
+        PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT);
+        assertEquals(0, newPoints.x, 0);
+        assertEquals(POINT_WIDTH, newPoints.y, 0);
+    }
+
+    @Test
+    public void rotate_180_bottomRight() {
+        RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_180,
+                POINT_WIDTH, POINT_HEIGHT, mMatrix);
+        PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT);
+        assertEquals(0, newPoints.x, 0);
+        assertEquals(0, newPoints.y, 0);
+    }
+
+    @Test
+    public void rotate_270_bottomRight() {
+        RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_270,
+                POINT_WIDTH, POINT_HEIGHT, mMatrix);
+        PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT);
+        assertEquals(POINT_HEIGHT, newPoints.x, 0);
+        assertEquals(0, newPoints.y, 0);
+    }
+
+    private PointF checkMappedPoints(int x, int y) {
+        final float[] fs = new float[] {x, y};
+        mMatrix.mapPoints(fs);
+        return new PointF(fs[0], fs[1]);
+    }
+
+    private Bitmap createBitmap(float luma) {
+        Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, ARGB_8888);
+        for (int i = 0; i < BITMAP_WIDTH; i++) {
+            for (int j = 0; j < BITMAP_HEIGHT; j++) {
+                bitmap.setPixel(i, j, Color.argb(1, luma, luma, luma));
+            }
+        }
+        return bitmap;
+    }
+
+    private GraphicBuffer swBitmapToGraphicsBuffer(Bitmap swBitmap) {
+        Bitmap hwBitmap = swBitmap.copy(Bitmap.Config.HARDWARE, false);
+        return hwBitmap.createGraphicBufferHandle();
+    }
+
+    private void setBorderLuma(Bitmap swBitmap, float luma) {
+        int i;
+        int width = swBitmap.getWidth();
+        int height = swBitmap.getHeight();
+        for (i = 0; i < width; i++) {
+            swBitmap.setPixel(i, 0, Color.argb(1, luma, luma, luma));
+            swBitmap.setPixel(i, height - 1, Color.argb(1, luma, luma, luma));
+        }
+        for (i = 0; i < height; i++) {
+            swBitmap.setPixel(0, i, Color.argb(1, luma, luma, luma));
+            swBitmap.setPixel(width - 1, i, Color.argb(1, luma, luma, luma));
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 27531949..b1bd04e 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -56,6 +56,8 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.dump.DualDumpOutputStream;
+import com.android.server.FgThread;
+import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
 
 import java.io.File;
@@ -64,6 +66,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * UsbService manages all USB related state, including both host and device support.
@@ -74,6 +77,9 @@
 
     public static class Lifecycle extends SystemService {
         private UsbService mUsbService;
+        private final CompletableFuture<Void> mOnStartFinished = new CompletableFuture<>();
+        private final CompletableFuture<Void> mOnActivityManagerPhaseFinished =
+                new CompletableFuture<>();
 
         public Lifecycle(Context context) {
             super(context);
@@ -81,32 +87,41 @@
 
         @Override
         public void onStart() {
-            mUsbService = new UsbService(getContext());
-            publishBinderService(Context.USB_SERVICE, mUsbService);
+            SystemServerInitThreadPool.submit(() -> {
+                mUsbService = new UsbService(getContext());
+                publishBinderService(Context.USB_SERVICE, mUsbService);
+                mOnStartFinished.complete(null);
+            }, "UsbService$Lifecycle#onStart");
         }
 
         @Override
         public void onBootPhase(int phase) {
             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
-                mUsbService.systemReady();
+                SystemServerInitThreadPool.submit(() -> {
+                    mOnStartFinished.join();
+                    mUsbService.systemReady();
+                    mOnActivityManagerPhaseFinished.complete(null);
+                }, "UsbService$Lifecycle#onBootPhase");
             } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+                mOnActivityManagerPhaseFinished.join();
                 mUsbService.bootCompleted();
             }
         }
 
         @Override
-        public void onSwitchUser(int newUserId) {
-            mUsbService.onSwitchUser(newUserId);
+        public void onSwitchUser(TargetUser from, TargetUser to) {
+            FgThread.getHandler()
+                    .postAtFrontOfQueue(() -> mUsbService.onSwitchUser(to.getUserIdentifier()));
         }
 
         @Override
-        public void onStopUser(int userHandle) {
-            mUsbService.onStopUser(UserHandle.of(userHandle));
+        public void onStopUser(TargetUser userInfo) {
+            mUsbService.onStopUser(userInfo.getUserHandle());
         }
 
         @Override
-        public void onUnlockUser(int userHandle) {
-            mUsbService.onUnlockUser(userHandle);
+        public void onUnlockUser(TargetUser userInfo) {
+            mUsbService.onUnlockUser(userInfo.getUserIdentifier());
         }
     }
 
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index c4c1e21..c3fb510 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -849,6 +849,17 @@
      */
     public static final int PRESENTATION_PAYPHONE = 4;
 
+
+    /*
+     * Values for the adb property "persist.radio.videocall.audio.output"
+     */
+    /** @hide */
+    public static final int AUDIO_OUTPUT_ENABLE_SPEAKER = 0;
+    /** @hide */
+    public static final int AUDIO_OUTPUT_DISABLE_SPEAKER = 1;
+    /** @hide */
+    public static final int AUDIO_OUTPUT_DEFAULT = AUDIO_OUTPUT_ENABLE_SPEAKER;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index f39981f..f3e9de0 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -24,20 +24,16 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
 import android.location.LocationManager;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.Log;
 import android.widget.Toast;
 
 import com.android.internal.telephony.util.TelephonyUtils;
 
-import java.util.List;
-
 /**
  * Helper for performing location access checks.
  * @hide
@@ -309,7 +305,7 @@
     }
 
     private static boolean checkSystemLocationAccess(@NonNull Context context, int uid, int pid) {
-        if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) {
+        if (!isLocationModeEnabled(context, UserHandle.getUserHandleForUid(uid).getIdentifier())) {
             if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")");
             return false;
         }
@@ -336,20 +332,17 @@
     private static boolean isCurrentProfile(@NonNull Context context, int uid) {
         long token = Binder.clearCallingIdentity();
         try {
-            final int currentUser = ActivityManager.getCurrentUser();
-            final int callingUserId = UserHandle.getUserId(uid);
-            if (callingUserId == currentUser) {
+            if (UserHandle.getUserHandleForUid(uid).getIdentifier()
+                    == ActivityManager.getCurrentUser()) {
                 return true;
-            } else {
-                List<UserInfo> userProfiles = context.getSystemService(
-                        UserManager.class).getProfiles(currentUser);
-                for (UserInfo user : userProfiles) {
-                    if (user.id == callingUserId) {
-                        return true;
-                    }
-                }
             }
-            return false;
+            ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+            if (activityManager != null) {
+                return activityManager.isProfileForeground(
+                        UserHandle.getUserHandleForUid(ActivityManager.getCurrentUser()));
+            } else {
+                return false;
+            }
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index b8b203d..89cd461 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -558,7 +558,7 @@
         }
 
         if (DBG) {
-            Log.d(LOG_TAG, "No READ_PRIVILEDED_PHONE_STATE permission, "
+            Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE permission, "
                     + "check carrier privilege next.");
         }
 
@@ -566,6 +566,33 @@
     }
 
     /**
+     * Ensure the caller (or self, if not processing an IPC) has
+     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
+     * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or carrier privileges.
+     *
+     * @throws SecurityException if the caller does not have the required permission/privileges
+     */
+    public static void enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+            Context context, int subId, String message) {
+        if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+                == PERMISSION_GRANTED) {
+            return;
+        }
+
+        if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+                == PERMISSION_GRANTED) {
+            return;
+        }
+
+        if (DBG) {
+            Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE nor READ_PRECISE_PHONE_STATE permission"
+                    + ", check carrier privilege next.");
+        }
+
+        enforceCallingOrSelfCarrierPrivilege(context, subId, message);
+    }
+
+    /**
      * Make sure the caller (or self, if not processing an IPC) has carrier privileges.
      *
      * @throws SecurityException if the caller does not have the required privileges
diff --git a/telephony/framework-telephony-jarjar-rules.txt b/telephony/framework-telephony-jarjar-rules.txt
index 7cab806..212eba1 100644
--- a/telephony/framework-telephony-jarjar-rules.txt
+++ b/telephony/framework-telephony-jarjar-rules.txt
@@ -1,4 +1,9 @@
 rule android.telephony.Annotation* android.telephony.framework.Annotation@1
+rule android.util.RecurrenceRule* android.telephony.RecurrenceRule@1
 rule com.android.i18n.phonenumbers.** com.android.telephony.framework.phonenumbers.@1
-#TODO: add jarjar rules for statically linked util classes
-
+rule com.android.internal.os.SomeArgs* android.telephony.SomeArgs@1
+rule com.android.internal.util.BitwiseInputStream* android.telephony.BitwiseInputStream@1
+rule com.android.internal.util.BitwiseOutputStream* android.telephony.BitwiseOutputStream@1
+rule com.android.internal.util.Preconditions* android.telephony.Preconditions@1
+rule com.android.internal.util.IndentingPrintWriter* android.telephony.IndentingPrintWriter@1
+rule com.android.internal.util.HexDump* android.telephony.HexDump@1
diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java
index bc6a9e8..ef11f46 100644
--- a/telephony/java/android/service/euicc/EuiccService.java
+++ b/telephony/java/android/service/euicc/EuiccService.java
@@ -34,6 +34,8 @@
 import android.telephony.euicc.EuiccManager.OtaStatus;
 import android.util.Log;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -583,6 +585,13 @@
     public abstract int onRetainSubscriptionsForFactoryReset(int slotId);
 
     /**
+     * Dump to a provided printWriter.
+     */
+    public void dump(@NonNull PrintWriter printWriter) {
+        printWriter.println("The connected LPA does not implement EuiccService#dump()");
+    }
+
+    /**
      * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}.
      */
     private class IEuiccServiceWrapper extends IEuiccService.Stub {
@@ -834,5 +843,22 @@
                 }
             });
         }
+
+        @Override
+        public void dump(IEuiccServiceDumpResultCallback callback) throws RemoteException {
+            mExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        final StringWriter sw = new StringWriter();
+                        final PrintWriter pw = new PrintWriter(sw);
+                        EuiccService.this.dump(pw);
+                        callback.onComplete(sw.toString());
+                    } catch (RemoteException e) {
+                        // Can't communicate with the phone process; ignore.
+                    }
+                }
+            });
+        }
     }
 }
diff --git a/telephony/java/android/service/euicc/IEuiccService.aidl b/telephony/java/android/service/euicc/IEuiccService.aidl
index 2acc47a..bb7b569 100644
--- a/telephony/java/android/service/euicc/IEuiccService.aidl
+++ b/telephony/java/android/service/euicc/IEuiccService.aidl
@@ -29,6 +29,7 @@
 import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
 import android.service.euicc.ISwitchToSubscriptionCallback;
 import android.service.euicc.IUpdateSubscriptionNicknameCallback;
+import android.service.euicc.IEuiccServiceDumpResultCallback;
 import android.telephony.euicc.DownloadableSubscription;
 import android.os.Bundle;
 
@@ -56,4 +57,5 @@
             int slotIndex, int options, in IEraseSubscriptionsCallback callback);
     void retainSubscriptionsForFactoryReset(
             int slotId, in IRetainSubscriptionsForFactoryResetCallback callback);
+    void dump(in IEuiccServiceDumpResultCallback callback);
 }
\ No newline at end of file
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index bb28df2..d325cd8 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -50,18 +50,12 @@
 
     /**
      * Transport type for Wireless Wide Area Networks (i.e. Cellular)
-     * @hide
      */
-    @SystemApi
-    @TestApi
     public static final int TRANSPORT_TYPE_WWAN = 1;
 
     /**
      * Transport type for Wireless Local Area Networks (i.e. Wifi)
-     * @hide
      */
-    @SystemApi
-    @TestApi
     public static final int TRANSPORT_TYPE_WLAN = 2;
 
     /** @hide */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5a7c3b3..ff31d3e 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1575,7 +1575,10 @@
     public static final String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
     public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
     public static final String KEY_MMS_USER_AGENT_STRING = "userAgent";
-    /** @hide */
+    /**
+     * If true, add "Connection: close" header to MMS HTTP requests so the connection
+     * is immediately closed (disabling keep-alive).
+     */
     public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection";
 
     /**
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index 475c99b..ec86c14 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.radio.V1_4.CellInfo.Info;
 import android.os.Parcel;
@@ -179,6 +180,18 @@
      *
      * @return a time stamp in nanos since boot.
      */
+    @SuppressLint("MethodNameUnits")
+    public long getTimestampNanos() {
+        return mTimeStamp;
+    }
+
+    /**
+     * Approximate time this cell information was received from the modem.
+     *
+     * @return a time stamp in nanos since boot.
+     * @deprecated Use {@link #getTimestampNanos} instead.
+     */
+    @Deprecated
     public long getTimeStamp() {
         return mTimeStamp;
     }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index cbd5ed6..32ffb75 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -36,10 +36,7 @@
 
 /**
  * Description of a mobile network registration info
- * @hide
  */
-@SystemApi
-@TestApi
 public final class NetworkRegistrationInfo implements Parcelable {
     /**
      * Network domain
@@ -51,9 +48,9 @@
 
     /** Unknown / Unspecified domain */
     public static final int DOMAIN_UNKNOWN = 0;
-    /** Circuit switching domain */
+    /** Circuit switched domain */
     public static final int DOMAIN_CS = android.hardware.radio.V1_5.Domain.CS;
-    /** Packet switching domain */
+    /** Packet switched domain */
     public static final int DOMAIN_PS = android.hardware.radio.V1_5.Domain.PS;
     /** Applicable to both CS and PS Domain */
     public static final int DOMAIN_CS_PS = DOMAIN_CS | DOMAIN_PS;
@@ -69,17 +66,41 @@
                     REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING})
     public @interface RegistrationState {}
 
-    /** Not registered. The device is not currently searching a new operator to register. */
+    /**
+     * Not registered. The device is not currently searching a new operator to register.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
-    /** Registered on home network. */
+    /**
+     * Registered on home network.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_HOME = 1;
-    /** Not registered. The device is currently searching a new operator to register. */
+    /**
+     * Not registered. The device is currently searching a new operator to register.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
-    /** Registration denied. */
+    /**
+     * Registration denied.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_DENIED = 3;
-    /** Registration state is unknown. */
+    /**
+     * Registration state is unknown.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_UNKNOWN = 4;
-    /** Registered on roaming network. */
+    /**
+     * Registered on roaming network.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_ROAMING = 5;
 
     /** @hide */
@@ -92,7 +113,6 @@
     /**
      * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR
      * Dual Connectivity(EN-DC).
-     * @hide
      */
     public static final int NR_STATE_NONE = 0;
 
@@ -100,7 +120,6 @@
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
      * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by
      * the selected PLMN.
-     * @hide
      */
     public static final int NR_STATE_RESTRICTED = 1;
 
@@ -108,14 +127,12 @@
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both
      * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the
      * selected PLMN.
-     * @hide
      */
     public static final int NR_STATE_NOT_RESTRICTED = 2;
 
     /**
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and
      * also connected to at least one 5G cell as a secondary serving cell.
-     * @hide
      */
     public static final int NR_STATE_CONNECTED = 3;
 
@@ -129,22 +146,34 @@
                     SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY})
     public @interface ServiceType {}
 
-    /** Unkown service */
+    /**
+     * Unknown service
+     */
     public static final int SERVICE_TYPE_UNKNOWN    = 0;
 
-    /** Voice service */
+    /**
+     * Voice service
+     */
     public static final int SERVICE_TYPE_VOICE      = 1;
 
-    /** Data service */
+    /**
+     * Data service
+     */
     public static final int SERVICE_TYPE_DATA       = 2;
 
-    /** SMS service */
+    /**
+     * SMS service
+     */
     public static final int SERVICE_TYPE_SMS        = 3;
 
-    /** Video service */
+    /**
+     * Video service
+     */
     public static final int SERVICE_TYPE_VIDEO      = 4;
 
-    /** Emergency service */
+    /**
+     * Emergency service
+     */
     public static final int SERVICE_TYPE_EMERGENCY  = 5;
 
     @Domain
@@ -330,9 +359,7 @@
      * Get the 5G NR connection state.
      *
      * @return the 5G NR connection state.
-     * @hide
      */
-    @SystemApi
     public @NRState int getNrState() {
         return mNrState;
     }
@@ -344,7 +371,10 @@
 
     /**
      * @return The registration state.
+     *
+     * @hide
      */
+    @SystemApi @TestApi
     public @RegistrationState int getRegistrationState() {
         return mRegistrationState;
     }
@@ -352,6 +382,21 @@
     /**
      * @return {@code true} if registered on roaming network, {@code false} otherwise.
      */
+    public boolean isRegistered() {
+        return mRegistrationState == REGISTRATION_STATE_HOME
+                || mRegistrationState == REGISTRATION_STATE_ROAMING;
+    }
+
+    /**
+     * @return {@code true} if registered on roaming network, {@code false} otherwise.
+     */
+    public boolean isSearching() {
+        return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
+    }
+
+    /**
+     * @return {@code true} if registered on roaming network, {@code false} otherwise.
+     */
     public boolean isRoaming() {
         return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
     }
@@ -376,15 +421,18 @@
 
     /**
      * @return the current network roaming type.
+     * @hide
      */
-
+    @SystemApi @TestApi
     public @ServiceState.RoamingType int getRoamingType() {
         return mRoamingType;
     }
 
     /**
      * @return Whether emergency is enabled.
+     * @hide
      */
+    @SystemApi @TestApi
     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
 
     /**
@@ -422,7 +470,9 @@
      * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}.
      * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
      * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA
+     * @hide
      */
+    @SystemApi @TestApi
     public int getRejectCause() {
         return mRejectCause;
     }
@@ -445,8 +495,10 @@
 
     /**
      * @return Data registration related info
+     * @hide
      */
     @Nullable
+    @SystemApi @TestApi
     public DataSpecificRegistrationInfo getDataSpecificInfo() {
         return mDataSpecificInfo;
     }
@@ -571,7 +623,11 @@
                 && mNrState == other.mNrState;
     }
 
+    /**
+     * @hide
+     */
     @Override
+    @SystemApi @TestApi
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mDomain);
         dest.writeInt(mTransportType);
@@ -659,7 +715,9 @@
      *     .setRegistrationState(REGISTRATION_STATE_HOME)
      *     .build();
      * </code></pre>
+     * @hide
      */
+    @SystemApi @TestApi
     public static final class Builder {
         @Domain
         private int mDomain;
@@ -759,7 +817,9 @@
          * @param emergencyOnly True if this network registration is for emergency use only.
          *
          * @return The same instance of the builder.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
             mEmergencyOnly = emergencyOnly;
             return this;
@@ -771,7 +831,9 @@
          * @param availableServices Available services.
          *
          * @return The same instance of the builder.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull Builder setAvailableServices(
                 @NonNull @ServiceType List<Integer> availableServices) {
             mAvailableServices = availableServices;
@@ -784,7 +846,9 @@
          * @param cellIdentity The cell identity.
          *
          * @return The same instance of the builder.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
             mCellIdentity = cellIdentity;
             return this;
@@ -792,9 +856,10 @@
 
         /**
          * Build the NetworkRegistrationInfo.
-         *
          * @return the NetworkRegistrationInfo object.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull NetworkRegistrationInfo build() {
             return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java
new file mode 100644
index 0000000..c14bd91
--- /dev/null
+++ b/telephony/java/android/telephony/PinResult.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.telephony.PhoneConstants;
+
+import java.util.Objects;
+
+/**
+ * Holds the result from a pin attempt.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PinResult implements Parcelable {
+    /** @hide */
+    @IntDef({
+            PIN_RESULT_TYPE_SUCCESS,
+            PIN_RESULT_TYPE_INCORRECT,
+            PIN_RESULT_TYPE_FAILURE,
+    })
+    public @interface PinResultType {}
+
+    /**
+     * Indicates that the pin attempt was a success.
+     */
+    public static final int PIN_RESULT_TYPE_SUCCESS = PhoneConstants.PIN_RESULT_SUCCESS;
+
+    /**
+     * Indicates that the pin attempt was incorrect.
+     */
+    public static final int PIN_RESULT_TYPE_INCORRECT = PhoneConstants.PIN_PASSWORD_INCORRECT;
+
+    /**
+     * Indicates that the pin attempt was a failure.
+     */
+    public static final int PIN_RESULT_TYPE_FAILURE = PhoneConstants.PIN_GENERAL_FAILURE;
+
+    private static final PinResult sFailedResult =
+            new PinResult(PinResult.PIN_RESULT_TYPE_FAILURE, -1);
+
+    private final @PinResultType int mType;
+
+    private final int mAttemptsRemaining;
+
+    /**
+     * Returns either success, incorrect or failure.
+     *
+     * @see #PIN_RESULT_TYPE_SUCCESS
+     * @see #PIN_RESULT_TYPE_INCORRECT
+     * @see #PIN_RESULT_TYPE_FAILURE
+     * @return The result type of the pin attempt.
+     */
+    public @PinResultType int getType() {
+        return mType;
+    }
+
+    /**
+     * The number of pin attempts remaining.
+     *
+     * @return Number of attempts remaining.
+     */
+    public int getAttemptsRemaining() {
+        return mAttemptsRemaining;
+    }
+
+    @NonNull
+    public static PinResult getDefaultFailedResult() {
+        return sFailedResult;
+    }
+
+    /**
+     * PinResult constructor
+     *
+     * @param type The type of pin result.
+     * @see #PIN_RESULT_TYPE_SUCCESS
+     * @see #PIN_RESULT_TYPE_INCORRECT
+     * @see #PIN_RESULT_TYPE_FAILURE
+     * @param attemptsRemaining Number of pin attempts remaining.
+     */
+    public PinResult(@PinResultType int type, int attemptsRemaining) {
+        mType = type;
+        mAttemptsRemaining = attemptsRemaining;
+    }
+
+    /**
+     * Construct a PinResult object from the given parcel.
+     *
+     * @hide
+     */
+    private PinResult(Parcel in) {
+        mType = in.readInt();
+        mAttemptsRemaining = in.readInt();
+    }
+
+    /**
+     * String representation of the Pin Result.
+     */
+    @NonNull
+    @Override
+    public String toString() {
+        return "type: " + getType() + ", attempts remaining: " + getAttemptsRemaining();
+    }
+
+    /**
+     * Required to be Parcelable
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Required to be Parcelable
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(mType);
+        out.writeInt(mAttemptsRemaining);
+    }
+
+    /** Required to be Parcelable */
+    public static final @NonNull Parcelable.Creator<PinResult> CREATOR = new Creator<PinResult>() {
+        public PinResult createFromParcel(Parcel in) {
+            return new PinResult(in);
+        }
+        public PinResult[] newArray(int size) {
+            return new PinResult[size];
+        }
+    };
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAttemptsRemaining, mType);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PinResult other = (PinResult) obj;
+        return (mType == other.mType
+                && mAttemptsRemaining == other.mAttemptsRemaining);
+    }
+}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 2c8014e..1e64a81 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1855,10 +1855,8 @@
      * Get all of the available network registration info.
      *
      * @return List of {@link NetworkRegistrationInfo}
-     * @hide
      */
     @NonNull
-    @SystemApi
     public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() {
         synchronized (mNetworkRegistrationInfos) {
             List<NetworkRegistrationInfo> newList = new ArrayList<>();
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 1c58f8f..5a4dac5 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -16,9 +16,8 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -26,6 +25,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+import android.os.SystemClock;
+
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -77,6 +79,9 @@
     /* The type of signal measurement */
     private static final String MEASUREMENT_TYPE_RSCP = "rscp";
 
+    // timeStamp of signalStrength in nanoseconds since boot
+    private long mTimestamp = Long.MAX_VALUE;
+
     CellSignalStrengthCdma mCdma;
     CellSignalStrengthGsm mGsm;
     CellSignalStrengthWcdma mWcdma;
@@ -134,6 +139,7 @@
         mTdscdma = tdscdma;
         mLte = lte;
         mNr = nr;
+        mTimestamp = SystemClock.elapsedRealtimeNanos();
     }
 
     /**
@@ -268,6 +274,7 @@
         mTdscdma.updateLevel(cc, ss);
         mLte.updateLevel(cc, ss);
         mNr.updateLevel(cc, ss);
+        mTimestamp = SystemClock.elapsedRealtimeNanos();
     }
 
     /**
@@ -293,6 +300,7 @@
         mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma);
         mLte = new CellSignalStrengthLte(s.mLte);
         mNr = new CellSignalStrengthNr(s.mNr);
+        mTimestamp = s.getTimestampNanos();
     }
 
     /**
@@ -310,6 +318,7 @@
         mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader());
         mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
         mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
+        mTimestamp = in.readLong();
     }
 
     /**
@@ -322,9 +331,18 @@
         out.writeParcelable(mTdscdma, flags);
         out.writeParcelable(mLte, flags);
         out.writeParcelable(mNr, flags);
+        out.writeLong(mTimestamp);
     }
 
     /**
+     * @return mTimestamp in nanoseconds
+     */
+    @SuppressLint("MethodNameUnits")
+    public long getTimestampNanos() {
+        return mTimestamp;
+    }
+
+   /**
      * {@link Parcelable#describeContents}
      */
     public int describeContents() {
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index fee6d3f..2f95a50 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -424,7 +424,26 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                true /* persistMessage*/, null);
+                true /* persistMessage*/, null, 0L /* messageId */);
+    }
+
+
+    /**
+     * Send a text based SMS. Same as {@link #sendTextMessage( String destinationAddress,
+     * String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)}, but
+     * adds an optional messageId.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     * Used for logging and diagnostics purposes. The id may be 0.
+     *
+     * @throws IllegalArgumentException if destinationAddress or text are empty
+     *
+     */
+    public void sendTextMessage(
+            @NonNull String destinationAddress, @Nullable String scAddress, @NonNull String text,
+            @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent,
+            long messageId) {
+        sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+                true /* persistMessage*/, null, messageId);
     }
 
     /**
@@ -542,7 +561,7 @@
 
     private void sendTextMessageInternal(String destinationAddress, String scAddress,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            boolean persistMessage, String packageName) {
+            boolean persistMessage, String packageName, long messageId) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -569,10 +588,10 @@
                     try {
                         iSms.sendTextForSubscriber(subId, packageName,
                                 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                                persistMessage);
+                                persistMessage, messageId);
                     } catch (RemoteException e) {
                         Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
-                                + e.getMessage());
+                                + e.getMessage() + " id: " + messageId);
                         notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
                     }
                 }
@@ -589,10 +608,10 @@
             try {
                 iSms.sendTextForSubscriber(getSubscriptionId(), packageName,
                         destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                        persistMessage);
+                        persistMessage, messageId);
             } catch (RemoteException e) {
                 Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - "
-                        + e.getMessage());
+                        + e.getMessage() + " id: " + messageId);
                 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
             }
         }
@@ -634,7 +653,8 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                false /* persistMessage */, null);
+                false /* persistMessage */, null,
+                0L /* messageId */);
     }
 
     private void sendTextMessageInternal(
@@ -921,7 +941,26 @@
             String destinationAddress, String scAddress, ArrayList<String> parts,
             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, null);
+                deliveryIntents, true /* persistMessage*/, null,
+                0L /* messageId */);
+    }
+
+    /**
+     * Send a multi-part text based SMS. Same as #sendMultipartTextMessage(String, String,
+     * ArrayList, ArrayList, ArrayList), but adds an optional messageId.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     * Used for logging and diagnostics purposes. The id may be 0.
+     *
+     * @throws IllegalArgumentException if destinationAddress or data are empty
+     *
+     */
+    public void sendMultipartTextMessage(
+            @NonNull String destinationAddress, @Nullable String scAddress,
+            @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
+            @Nullable List<PendingIntent> deliveryIntents, long messageId) {
+        sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+                deliveryIntents, true /* persistMessage*/, null,
+                messageId);
     }
 
     /**
@@ -946,17 +985,17 @@
     @SystemApi
     @TestApi
     public void sendMultipartTextMessage(
-            @NonNull String destinationAddress, @NonNull String scAddress,
+            @NonNull String destinationAddress, @Nullable String scAddress,
             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
             @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, packageName);
+                deliveryIntents, true /* persistMessage*/, packageName, 0L /* messageId */);
     }
 
     private void sendMultipartTextMessageInternal(
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
-            boolean persistMessage, String packageName) {
+            boolean persistMessage, String packageName, long messageId) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -983,10 +1022,11 @@
                             ISms iSms = getISmsServiceOrThrow();
                             iSms.sendMultipartTextForSubscriber(subId, packageName,
                                     destinationAddress, scAddress, parts, sentIntents,
-                                    deliveryIntents, persistMessage);
+                                    deliveryIntents, persistMessage, messageId);
                         } catch (RemoteException e) {
                             Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
-                                    + e.getMessage());
+                                    + e.getMessage() + " id: "
+                                    + messageId);
                             notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
                         }
                     }
@@ -1003,11 +1043,11 @@
                     if (iSms != null) {
                         iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
                                 destinationAddress, scAddress, parts, sentIntents, deliveryIntents,
-                                persistMessage);
+                                persistMessage, messageId);
                     }
                 } catch (RemoteException e) {
                     Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
-                            + e.getMessage());
+                            + e.getMessage() + " id: " + messageId);
                     notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
                 }
             }
@@ -1021,7 +1061,7 @@
                 deliveryIntent = deliveryIntents.get(0);
             }
             sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
-                    sentIntent, deliveryIntent, true, packageName);
+                    sentIntent, deliveryIntent, true, packageName, messageId);
         }
     }
 
@@ -1051,7 +1091,8 @@
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, false /* persistMessage*/, null);
+                deliveryIntents, false /* persistMessage*/, null,
+                0L /* messageId */);
     }
 
     /**
@@ -2545,16 +2586,6 @@
     /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */
     public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
 
-    /** Represents the received SMS message for importing {@hide} */
-    public static final int SMS_TYPE_INCOMING = 0;
-    /** Represents the sent SMS message for importing {@hide} */
-    public static final int SMS_TYPE_OUTGOING = 1;
-
-    /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */
-    public static final String MESSAGE_STATUS_SEEN = "seen";
-    /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */
-    public static final String MESSAGE_STATUS_READ = "read";
-
     /**
      * Get carrier-dependent MMS configuration values.
      *
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index b42ce35..8de5b85 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -782,6 +782,12 @@
     public static final String UICC_APPLICATIONS_ENABLED = SimInfo.UICC_APPLICATIONS_ENABLED;
 
     /**
+     * Indicate which network type is allowed. By default it's enabled.
+     * @hide
+     */
+    public static final String ALLOWED_NETWORK_TYPES = SimInfo.ALLOWED_NETWORK_TYPES;
+
+    /**
      * Broadcast Action: The user has changed one of the default subs related to
      * data, phone calls, or sms</p>
      *
@@ -2434,7 +2440,28 @@
             try {
                 return Integer.parseInt(result);
             } catch (NumberFormatException err) {
-                logd("getBooleanSubscriptionProperty NumberFormat exception");
+                logd("getIntegerSubscriptionProperty NumberFormat exception");
+            }
+        }
+        return defValue;
+    }
+
+    /**
+     * Returns long value corresponding to query result.
+     * @param subId Subscription Id of Subscription
+     * @param propKey Column name in SubscriptionInfo database
+     * @param defValue Default long value to be returned
+     * @return long result value to be returned
+     * @hide
+     */
+    public static long getLongSubscriptionProperty(int subId, String propKey, long defValue,
+                                                     Context context) {
+        String result = getSubscriptionProperty(subId, propKey, context);
+        if (result != null) {
+            try {
+                return Long.parseLong(result);
+            } catch (NumberFormatException err) {
+                logd("getLongSubscriptionProperty NumberFormat exception");
             }
         }
         return defValue;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 56ca8c7..c9d5006 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3859,21 +3859,20 @@
     }
 
     /**
-     * Return if the current radio is LTE on CDMA. This is a tri-state return value as for a period
-     * of time the mode may be unknown.
+     * Return if the current radio has global mode enabled, meaning it supports
+     * both 3GPP and 3GPP2 radio technologies at the same time.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
-     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
-     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
-     *
+     * @return {@code true} if global mode is enabled
+     *         {@code false} if global mode is not enabled or unknown
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    @UnsupportedAppUsage
-    public int getLteOnCdmaMode() {
-        return getLteOnCdmaMode(getSubId());
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isGlobalModeEnabled() {
+        return getLteOnCdmaMode(getSubId()) == PhoneConstants.LTE_ON_CDMA_TRUE;
     }
 
     /**
@@ -3886,7 +3885,7 @@
      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @UnsupportedAppUsage
     public int getLteOnCdmaMode(int subId) {
         try {
@@ -7688,7 +7687,9 @@
      *
      * @return the preferred network type.
      * @hide
+     * @deprecated Use {@link #getPreferredNetworkTypeBitmask} instead.
      */
+    @Deprecated
     @RequiresPermission((android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE))
     @UnsupportedAppUsage
     public @PrefNetworkMode int getPreferredNetworkType(int subId) {
@@ -7733,6 +7734,30 @@
     }
 
     /**
+     * Get the allowed network types.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
+     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @return the allowed network type bitmask
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SystemApi
+    public @NetworkTypeBitMask long getAllowedNetworkTypes() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getAllowedNetworkTypes(getSubId());
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getAllowedNetworkTypes RemoteException", ex);
+        }
+        return -1;
+    }
+
+    /**
      * Sets the network selection mode to automatic.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
@@ -7983,7 +8008,9 @@
      * @param networkType the preferred network type
      * @return true on success; false on any failure.
      * @hide
+     * @deprecated Use {@link #setPreferredNetworkTypeBitmask} instead.
      */
+    @Deprecated
     @UnsupportedAppUsage
     public boolean setPreferredNetworkType(int subId, @PrefNetworkMode int networkType) {
         try {
@@ -7998,7 +8025,8 @@
     }
 
     /**
-     * Set the preferred network type bitmask.
+     * Set the preferred network type bitmask but if {@link #setAllowedNetworkTypes} has been set,
+     * only the allowed network type will set to the modem.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
      * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
@@ -8028,6 +8056,29 @@
     }
 
     /**
+     * Set the allowed network types of the device. This is for carrier or privileged apps to
+     * enable/disable certain network types on the device. The user preferred network types should
+     * be set through {@link #setPreferredNetworkTypeBitmask}.
+     *
+     * @param allowedNetworkTypes The bitmask of allowed network types.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
+    public boolean setAllowedNetworkTypes(@NetworkTypeBitMask long allowedNetworkTypes) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.setAllowedNetworkTypes(getSubId(), allowedNetworkTypes);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setAllowedNetworkTypes RemoteException", ex);
+        }
+        return false;
+    }
+
+    /**
      * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA.
      *
      * <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
@@ -8548,9 +8599,13 @@
         return false;
     }
 
-    /** @hide */
+    /**
+     * @deprecated use {@link #supplyPinReportPinResult(String pin)} instead.
+     *
+     * @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @Deprecated
     public int[] supplyPinReportResult(String pin) {
         try {
             ITelephony telephony = getITelephony();
@@ -8562,9 +8617,13 @@
         return new int[0];
     }
 
-    /** @hide */
+    /**
+     * @deprecated use {@link #supplyPukReportPinResult(String puk, String pin)} instead.
+     *
+     * @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @Deprecated
     public int[] supplyPukReportResult(String puk, String pin) {
         try {
             ITelephony telephony = getITelephony();
@@ -8577,6 +8636,55 @@
     }
 
     /**
+     * Used when the user attempts to enter their pin.
+     *
+     * @param pin The user entered pin.
+     * @return The result of the pin.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public PinResult supplyPinReportPinResult(@NonNull String pin) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                int[] result = telephony.supplyPinReportResultForSubscriber(getSubId(), pin);
+                return new PinResult(result[0], result[1]);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#supplyPinReportResultForSubscriber", e);
+        }
+        return null;
+    }
+
+    /**
+     * Used when the user attempts to enter the puk or their pin.
+     *
+     * @param puk The product unblocking key.
+     * @param pin The user entered pin.
+     * @return The result of the pin.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public PinResult supplyPukReportPinResult(@NonNull String puk, @NonNull String pin) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                int[] result = telephony.supplyPukReportResultForSubscriber(getSubId(), puk, pin);
+                return new PinResult(result[0], result[1]);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#]", e);
+        }
+        return null;
+    }
+
+    /**
      * Used to notify callers of
      * {@link TelephonyManager#sendUssdRequest(String, UssdResponseCallback, Handler)} when the
      * network either successfully executes a USSD request, or if there was a failure while
@@ -9535,15 +9643,20 @@
     }
 
     /**
-     * Requested state of SIM
-     *
-     * CARD_POWER_DOWN
      * Powers down the SIM. SIM must be up prior.
-     *
-     * CARD_POWER_UP
+     * @hide
+     */
+    @SystemApi
+    public static final int CARD_POWER_DOWN = 0;
+
+    /**
      * Powers up the SIM normally. SIM must be down prior.
-     *
-     * CARD_POWER_UP_PASS_THROUGH
+     * @hide
+     */
+    @SystemApi
+    public static final int CARD_POWER_UP = 1;
+
+    /**
      * Powers up the SIM in PASS_THROUGH mode. SIM must be down prior.
      * When SIM is powered up in PASS_THOUGH mode, the modem does not send
      * any command to it (for example SELECT of MF, or TERMINAL CAPABILITY),
@@ -9556,12 +9669,9 @@
      * is activated, and normal behavior occurs at the next SIM initialization,
      * unless PASS_THROUGH mode is requested again. Hence, the last power-up mode
      * is NOT persistent across boots. On reboot, SIM will power up normally.
+     * @hide
      */
-    /** @hide */
-    public static final int CARD_POWER_DOWN = 0;
-    /** @hide */
-    public static final int CARD_POWER_UP = 1;
-    /** @hide */
+    @SystemApi
     public static final int CARD_POWER_UP_PASS_THROUGH = 2;
 
     /**
@@ -10981,9 +11091,15 @@
     }
 
     /**
-     * Checks if FEATURE_TELEPHONY_DATA is enabled.
-     *
-     * @hide
+     * @return true if the current device is "data capable" over a radio on the device.
+     * <p>
+     * "Data capable" means that this device supports packet-switched
+     * data connections over the telephony network.
+     * <p>
+     * Note: the meaning of this flag is subtly different from the
+     * PackageManager.FEATURE_TELEPHONY system feature, which is available
+     * on any device with a telephony radio, even if the device is
+     * voice-only.
      */
     public boolean isDataCapable() {
         if (mContext == null) return true;
@@ -12416,15 +12532,21 @@
     }
 
     /**
-     * Set allowing mobile data during voice call.
+     * Set allowing mobile data during voice call. This is used for allowing data on the non-default
+     * data SIM. When a voice call is placed on the non-default data SIM on DSDS devices, users will
+     * not be able to use mobile data. By calling this API, data will be temporarily enabled on the
+     * non-default data SIM during the life cycle of the voice call.
      *
      * @param allow {@code true} if allowing using data during voice call, {@code false} if
-     * disallowed
+     * disallowed.
      *
-     * @return {@code false} if the setting is changed.
+     * @return {@code true} if operation is successful. otherwise {@code false}.
+     *
+     * @throws SecurityException if the caller doesn't have the permission.
      *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setDataAllowedDuringVoiceCall(boolean allow) {
         try {
@@ -12433,6 +12555,7 @@
                 return service.setDataAllowedDuringVoiceCall(getSubId(), allow);
             }
         } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
             if (!isSystemProcess()) {
                 ex.rethrowAsRuntimeException();
             }
@@ -12441,13 +12564,18 @@
     }
 
     /**
-     * Check whether data is allowed during voice call. Note this is for dual sim device that
-     * data might be disabled on non-default data subscription but explicitly turned on by settings.
+     * Check whether data is allowed during voice call. This is used for allowing data on the
+     * non-default data SIM. When a voice call is placed on the non-default data SIM on DSDS
+     * devices, users will not be able to use mobile data. By calling this API, data will be
+     * temporarily enabled on the non-default data SIM during the life cycle of the voice call.
      *
      * @return {@code true} if data is allowed during voice call.
      *
+     * @throws SecurityException if the caller doesn't have the permission.
+     *
      * @hide
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public boolean isDataAllowedInVoiceCall() {
         try {
@@ -12456,6 +12584,7 @@
                 return service.isDataAllowedInVoiceCall(getSubId());
             }
         } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
             if (!isSystemProcess()) {
                 ex.rethrowAsRuntimeException();
             }
@@ -12488,4 +12617,108 @@
         }
         return false;
     }
+
+    /**
+     * The IccLock state or password was changed successfully.
+     * @hide
+     */
+    @SystemApi
+    public static final int CHANGE_ICC_LOCK_SUCCESS = Integer.MAX_VALUE;
+
+    /**
+     * Check whether ICC pin lock is enabled.
+     * This is a sync call which returns the cached pin enabled state.
+     *
+     * @return {@code true} if ICC lock enabled, {@code false} if ICC lock disabled.
+     *
+     * @throws SecurityException if the caller doesn't have the permission.
+     *
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isIccLockEnabled() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isIccLockEnabled(getSubId());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "isIccLockEnabled RemoteException", e);
+        }
+        return false;
+    }
+
+    /**
+     * Set the ICC pin lock enabled or disabled.
+     *
+     * If enable/disable ICC pin lock successfully, a value of {@link Integer#MAX_VALUE} is
+     * returned.
+     * If an incorrect old password is specified, the return value will indicate how many more
+     * attempts the user can make to change the password before the SIM is locked.
+     * Using PUK code to unlock SIM if enter the incorrect old password 3 times.
+     *
+     * @param enabled    "true" for locked, "false" for unlocked.
+     * @param password   needed to change the ICC pin state, aka. Pin1
+     * @return an integer representing the status of IccLock enabled or disabled in the following
+     * three cases:
+     *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
+     *   successfully.
+     *   - Positive number and zero for remaining password attempts.
+     *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
+     *
+     * @throws SecurityException if the caller doesn't have the permission.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public int setIccLockEnabled(boolean enabled, @NonNull String password) {
+        checkNotNull(password, "setIccLockEnabled password can't be null.");
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.setIccLockEnabled(getSubId(), enabled, password);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "setIccLockEnabled RemoteException", e);
+        }
+        return 0;
+    }
+
+    /**
+     * Change the ICC password used in ICC pin lock.
+     *
+     * If the password was changed successfully, a value of {@link Integer#MAX_VALUE} is returned.
+     * If an incorrect old password is specified, the return value will indicate how many more
+     * attempts the user can make to change the password before the SIM is locked.
+     * Using PUK code to unlock SIM if enter the incorrect old password 3 times.
+     *
+     * @param oldPassword is the old password
+     * @param newPassword is the new password
+     * @return an integer representing the status of IccLock changed in the following three cases:
+     *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
+     *   - Positive number and zero for remaining password attempts.
+     *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
+     *
+     * @throws SecurityException if the caller doesn't have the permission.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public int changeIccLockPassword(@NonNull String oldPassword, @NonNull String newPassword) {
+        checkNotNull(oldPassword, "changeIccLockPassword oldPassword can't be null.");
+        checkNotNull(newPassword, "changeIccLockPassword newPassword can't be null.");
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.changeIccLockPassword(getSubId(), oldPassword, newPassword);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "changeIccLockPassword RemoteException", e);
+        }
+        return 0;
+    }
 }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index fab1bf2..6e630e3 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -18,6 +18,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.hardware.radio.V1_5.ApnTypes;
@@ -28,13 +29,14 @@
 import android.provider.Telephony.Carriers;
 import android.telephony.Annotation.ApnType;
 import android.telephony.Annotation.NetworkType;
-import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.InetAddress;
@@ -123,6 +125,122 @@
     /** Authentication type for PAP or CHAP. */
     public static final int AUTH_TYPE_PAP_OR_CHAP = 3;
 
+    /**
+     * APN types for data connections.  These are usage categories for an APN
+     * entry.  One APN entry may support multiple APN types, eg, a single APN
+     * may service regular internet traffic ("default") as well as MMS-specific
+     * connections.<br/>
+     * APN_TYPE_ALL is a special type to indicate that this APN entry can
+     * service all data connections.
+     * <p>
+     * Note: The goal is to deprecate this.  Due to the Carrier Table being used
+     * directly, this isn't feasible right now.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_ALL_STRING = "*";
+
+    /**
+     * APN type for default data traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_DEFAULT_STRING = "default";
+
+
+    /**
+     * APN type for MMS traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_MMS_STRING = "mms";
+
+
+    /**
+     * APN type for SUPL assisted GPS
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_SUPL_STRING = "supl";
+
+    /**
+     * APN type for DUN traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_DUN_STRING = "dun";
+
+    /**
+     * APN type for HiPri traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_HIPRI_STRING = "hipri";
+
+    /**
+     * APN type for FOTA
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_FOTA_STRING = "fota";
+
+    /**
+     * APN type for IMS
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_IMS_STRING = "ims";
+
+    /**
+     * APN type for CBS
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_CBS_STRING = "cbs";
+
+    /**
+     * APN type for IA Initial Attach APN
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_IA_STRING = "ia";
+
+    /**
+     * APN type for Emergency PDN. This is not an IA apn, but is used
+     * for access to carrier services in an emergency call situation.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_EMERGENCY_STRING = "emergency";
+
+    /**
+     * APN type for Mission Critical Services
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_MCX_STRING = "mcx";
+
+    /**
+     * APN type for XCAP
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_XCAP_STRING = "xcap";
+
+
     /** @hide */
     @IntDef(prefix = { "AUTH_TYPE_" }, value = {
         AUTH_TYPE_NONE,
@@ -1289,10 +1407,13 @@
     }
 
     /**
+     * Converts the integer value of an APN type to the string version.
      * @param apnTypeBitmask bitmask of APN types.
      * @return comma delimited list of APN types.
      * @hide
      */
+    @SystemApi
+    @NonNull
     public static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
         List<String> types = new ArrayList<>();
         for (Integer type : APN_TYPE_INT_MAP.keySet()) {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index bc60d81..3f260eb 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -40,10 +41,11 @@
 import java.util.List;
 
 /**
- * Parcelable object to handle IMS call profile.
- * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
- * It provides the service and call type, the additional information related to the call.
- *
+ * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
+ * additional information related to the call.
+ * <p>
+ * See the following specifications for more information about this class: GSMA IR.92/IR.94,
+ * 3GPP TS 24.229/TS 26.114/TS26.111.
  * @hide
  */
 @SystemApi
@@ -151,12 +153,13 @@
      */
     public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
 
-    // Extra string for internal use only. OEMs should not use
-    // this for packing extras.
     /**
+     * Extra key used to store a Bundle containing proprietary extras to send to the ImsService.
+     * Use {@link #getProprietaryCallExtras()} instead.
      * @hide
      */
-    public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
+    @TestApi
+    public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
 
     /**
      * Rule for originating identity (number) presentation, MO/MT.
@@ -687,6 +690,18 @@
         return mCallExtras;
     }
 
+    /**
+     * Get the proprietary extras set for this ImsCallProfile.
+     * @return A {@link Bundle} containing proprietary call extras that were not set by the
+     * platform.
+     */
+    public @Nullable Bundle getProprietaryCallExtras() {
+        if (mCallExtras == null) {
+            return null;
+        }
+        return mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+    }
+
     public ImsStreamMediaProfile getMediaProfile() {
         return mMediaProfile;
     }
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index 39af2e7..cb3f0f9 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -30,10 +30,7 @@
 /**
  * This class defines an IMS-related exception that has been thrown while interacting with a
  * device or carrier provided ImsService implementation.
- * @hide
  */
-@SystemApi
-@TestApi
 public final class ImsException extends Exception {
 
     /**
@@ -83,7 +80,10 @@
     /**
      * A new {@link ImsException} with an unspecified {@link ImsErrorCode} code.
      * @param message an optional message to detail the error condition more specifically.
+     * @hide
      */
+    @SystemApi
+    @TestApi
     public ImsException(@Nullable String message) {
         super(getMessage(message, CODE_ERROR_UNSPECIFIED));
     }
@@ -91,7 +91,10 @@
     /**
      * A new {@link ImsException} that includes an {@link ImsErrorCode} error code.
      * @param message an optional message to detail the error condition more specifically.
+     * @hide
      */
+    @SystemApi
+    @TestApi
     public ImsException(@Nullable String message, @ImsErrorCode int code) {
         super(getMessage(message, code));
         mCode = code;
@@ -102,7 +105,10 @@
      * {@link Throwable} that contains the original error that was thrown to lead to this Exception.
      * @param message an optional message to detail the error condition more specifically.
      * @param cause the {@link Throwable} that caused this {@link ImsException} to be created.
+     * @hide
      */
+    @SystemApi
+    @TestApi
     public ImsException(@Nullable String message, @ImsErrorCode  int code,
             @Nullable Throwable cause) {
         super(getMessage(message, code), cause);
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 91514e9..5fdef83 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -23,6 +23,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressAutoDoc;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.Binder;
@@ -55,10 +57,7 @@
  * associated subscription.
  *
  * @see #createForSubscriptionId(int)
- * @hide
  */
-@SystemApi
-@TestApi
 public class ImsMmTelManager implements RegistrationManager {
 
     /**
@@ -93,9 +92,11 @@
      * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) (RegistrationCallback)
      * @see #unregisterImsRegistrationCallback(RegistrationCallback)
      * @deprecated Use {@link RegistrationManager.RegistrationCallback} instead.
+     * @hide
      */
     // Do not add to this class, add to RegistrationManager.RegistrationCallback instead.
     @Deprecated
+    @SystemApi @TestApi
     public static class RegistrationCallback extends RegistrationManager.RegistrationCallback {
 
         /**
@@ -140,7 +141,7 @@
 
     /**
      * Receives IMS capability status updates from the ImsService. This information is also
-     * available via the {@link #isAvailable(int, int)} method below.
+     * available via the {@see #isAvailable(int, int)} method below.
      *
      * @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback) (CapabilityCallback)
      * @see #unregisterMmTelCapabilityCallback(CapabilityCallback)
@@ -193,7 +194,7 @@
          * If unavailable, the feature is not able to support the unavailable capability at this
          * time.
          *
-         * This information can also be queried using the {@link #isAvailable(int, int)} API.
+         * This information can also be queried using the {@see #isAvailable(int, int)} API.
          *
          * @param capabilities The new availability of the capabilities.
          */
@@ -221,8 +222,20 @@
      *
      * @param subId The ID of the subscription that this ImsMmTelManager will use.
      * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
+     *
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
+     * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
+     *
      * @throws IllegalArgumentException if the subscription is invalid.
+     *
      */
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE
+    })
+    @SuppressLint("ManagerLookup")
     public static @NonNull ImsMmTelManager createForSubscriptionId(int subId) {
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             throw new IllegalArgumentException("Invalid subscription ID");
@@ -261,8 +274,10 @@
      * reason.
      * @deprecated Use {@link RegistrationManager#registerImsRegistrationCallback(Executor,
      * RegistrationManager.RegistrationCallback)} instead.
+     * @hide
      */
     @Deprecated
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull RegistrationCallback c) throws ImsException {
@@ -287,9 +302,20 @@
         }
     }
 
-    /**{@inheritDoc}*/
+     /**
+     *
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
+     * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
+     *
+     * {@inheritDoc}
+     *
+     */
     @Override
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull RegistrationManager.RegistrationCallback c) throws ImsException {
         if (c == null) {
@@ -320,8 +346,10 @@
      * @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
      * @deprecated Use {@link #unregisterImsRegistrationCallback(
      * RegistrationManager.RegistrationCallback)}.
+     * @hide
      */
     @Deprecated
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c) {
         if (c == null) {
@@ -334,9 +362,20 @@
         }
     }
 
-    /**{@inheritDoc}*/
+     /**
+     *
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
+     * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
+     *{@inheritDoc}
+     */
     @Override
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public void unregisterImsRegistrationCallback(
             @NonNull RegistrationManager.RegistrationCallback c) {
         if (c == null) {
@@ -349,9 +388,13 @@
         }
     }
 
-    /**{@inheritDoc}*/
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
     @Override
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SystemApi @TestApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
             @NonNull @ImsRegistrationState Consumer<Integer> stateCallback) {
         if (stateCallback == null) {
@@ -372,9 +415,19 @@
         }
     }
 
-    /**{@inheritDoc}*/
+    /**
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
+     * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
+     *{@inheritDoc}
+     */
     @Override
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public void getRegistrationTransportType(@NonNull @CallbackExecutor Executor executor,
             @NonNull @AccessNetworkConstants.TransportType
                     Consumer<Integer> transportTypeCallback) {
@@ -400,12 +453,25 @@
     /**
      * Registers a {@link CapabilityCallback} with the system, which will provide MmTel service
      * availability updates for the subscription specified in
-     * {@link #createForSubscriptionId(int)}. The method {@link #isAvailable(int, int)}
+     * {@link #createForSubscriptionId(int)}. The method {@see #isAvailable(int, int)}
      * can also be used to query this information at any time.
      *
      * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
      * subscription changed events and call
      * {@link #unregisterMmTelCapabilityCallback(CapabilityCallback)} to clean up.
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
      *
      * When the callback is registered, it will initiate the callback c to be called with the
      * current capabilities.
@@ -421,7 +487,10 @@
      * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
      * reason.
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public void registerMmTelCapabilityCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull CapabilityCallback c) throws ImsException {
         if (c == null) {
@@ -453,10 +522,27 @@
      * When the subscription associated with this callback is removed (SIM removed, ESIM swap,
      * etc...), this callback will automatically be removed. If this method is called for an
      * inactive subscription, it will result in a no-op.
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
      * @param c The MmTel {@link CapabilityCallback} to be removed.
      * @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback)
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public void unregisterMmTelCapabilityCallback(@NonNull CapabilityCallback c) {
         if (c == null) {
             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
@@ -478,6 +564,19 @@
      * <p>
      * Note: If the carrier configuration for advanced calling is not editable or hidden, this
      * method will always return the default value.
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
      *
      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
      * @see android.telephony.CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL
@@ -489,7 +588,10 @@
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @return true if the user's setting for advanced calling is enabled, false otherwise.
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public boolean isAdvancedCallingSettingEnabled() {
         try {
             return getITelephony().isAdvancedCallingSettingEnabled(mSubId);
@@ -527,8 +629,10 @@
      * @see #isAdvancedCallingSettingEnabled()
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
+     * @hide
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi @TestApi
     public void setAdvancedCallingSettingEnabled(boolean isEnabled) {
         try {
             getITelephony().setAdvancedCallingSettingEnabled(mSubId, isEnabled);
@@ -559,13 +663,15 @@
      *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
      * @param capability The IMS MmTel capability to query, can be one of the following:
      *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO,
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO},
      *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
      *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
      * @return {@code true} if the MmTel IMS capability is capable for this subscription, false
      *         otherwise.
+     * @hide
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SystemApi @TestApi
     public boolean isCapable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
         try {
@@ -586,12 +692,14 @@
      *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
      * @param capability The IMS MmTel capability to query, can be one of the following:
      *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
-     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO,
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO},
      *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
      *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
      * @return {@code true} if the MmTel IMS capability is available for this subscription, false
      *         otherwise.
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public boolean isAvailable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
@@ -616,7 +724,9 @@
      *                 capability is supported on this carrier network for the transport specified.
      * @throws ImsException if the subscription is no longer valid or the IMS service is not
      * available.
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void isSupported(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
             @AccessNetworkConstants.TransportType int transportType,
@@ -645,12 +755,32 @@
     /**
      * The user's setting for whether or not they have enabled the "Video Calling" setting.
      *
+     * <p>
+     * Note: If the carrier configuration for advanced calling is not editable or hidden, this
+     * method will always return the default value.
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @return true if the user’s “Video Calling” setting is currently enabled.
      * @see #setVtSettingEnabled(boolean)
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     public boolean isVtSettingEnabled() {
         try {
             return getITelephony().isVtSettingEnabled(mSubId);
@@ -672,7 +802,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #isVtSettingEnabled()
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setVtSettingEnabled(boolean isEnabled) {
         try {
@@ -692,11 +824,28 @@
     /**
      * @return true if the user's setting for Voice over WiFi is enabled and false if it is not.
      *
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #setVoWiFiSettingEnabled(boolean)
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public boolean isVoWiFiSettingEnabled() {
         try {
             return getITelephony().isVoWiFiSettingEnabled(mSubId);
@@ -719,7 +868,9 @@
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @param isEnabled true if the user's setting for Voice over WiFi is enabled, false otherwise=
      * @see #isVoWiFiSettingEnabled()
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setVoWiFiSettingEnabled(boolean isEnabled) {
         try {
@@ -739,13 +890,30 @@
     /**
      * Returns the user's voice over WiFi roaming setting associated with the current subscription.
      *
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @return true if the user's setting for Voice over WiFi while roaming is enabled, false
      * if disabled.
      * @see #setVoWiFiRoamingSettingEnabled(boolean)
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public boolean isVoWiFiRoamingSettingEnabled() {
         try {
             return getITelephony().isVoWiFiRoamingSettingEnabled(mSubId);
@@ -769,7 +937,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #isVoWiFiRoamingSettingEnabled()
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setVoWiFiRoamingSettingEnabled(boolean isEnabled) {
         try {
@@ -799,7 +969,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #setVoWiFiSettingEnabled(boolean)
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setVoWiFiNonPersistent(boolean isCapable, int mode) {
         try {
@@ -819,6 +991,20 @@
     /**
      * Returns the user's voice over WiFi Roaming mode setting associated with the device.
      *
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @return The Voice over WiFi Mode preference set by the user, which can be one of the
@@ -828,7 +1014,10 @@
      * - {@link #WIFI_MODE_WIFI_PREFERRED}
      * @see #setVoWiFiSettingEnabled(boolean)
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public @WiFiCallingMode int getVoWiFiModeSetting() {
         try {
             return getITelephony().getVoWiFiModeSetting(mSubId);
@@ -854,7 +1043,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #getVoWiFiModeSetting()
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setVoWiFiModeSetting(@WiFiCallingMode int mode) {
         try {
@@ -883,7 +1074,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #setVoWiFiRoamingSettingEnabled(boolean)
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
         try {
@@ -912,7 +1105,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see #getVoWiFiRoamingModeSetting()
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setVoWiFiRoamingModeSetting(@WiFiCallingMode int mode) {
         try {
@@ -939,7 +1134,9 @@
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @param isEnabled if true RTT should be enabled during calls made on this subscription.
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setRttCapabilitySetting(boolean isEnabled) {
         try {
@@ -959,12 +1156,29 @@
     /**
      * @return true if TTY over VoLTE is supported
      *
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see
+     *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
+     *     active subscription.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
+     *
      * @throws IllegalArgumentException if the subscription associated with this operation is not
      * active (SIM is not inserted, ESIM inactive) or invalid.
      * @see android.telecom.TelecomManager#getCurrentTtyMode
      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PRECISE_PHONE_STATE})
     public boolean isTtyOverVolteEnabled() {
         try {
             return getITelephony().isTtyOverVolteEnabled(mSubId);
@@ -991,7 +1205,9 @@
      *                 specified when the service state has been retrieved from the IMS service.
      * @throws ImsException if the IMS service associated with this subscription is not available or
      * the IMS service is not available.
+     * @hide
      */
+    @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public void getFeatureState(@NonNull @CallbackExecutor Executor executor,
             @NonNull @ImsFeature.ImsState Consumer<Integer> callback) throws ImsException {
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index 893a311..3e2903f 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -83,8 +83,23 @@
     public static final int CAPABILITY_RCS_VOICE_CALL = (1 << 19);
     /** Supports RCS video calling */
     public static final int CAPABILITY_RCS_VIDEO_CALL = (1 << 20);
-    /** Supports RCS video calling, where video media can not be dropped */
+    /** Supports RCS video calling, where video media can not be dropped. */
     public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = (1 << 21);
+    /** Supports call composer, where outgoing calls can be enriched with pre-call content.*/
+    public static final int CAPABILITY_CALL_COMPOSER = (1 << 22);
+    /** Supports post call information that is included in the call if the call is missed.*/
+    public static final int CAPABILITY_POST_CALL = (1 << 23);
+    /** Supports sharing a map where the user can draw, share markers, and share their position. */
+    public static final int CAPABILITY_SHARED_MAP = (1 << 24);
+    /** Supports sharing a canvas, where users can draw, add images, and change background colors.*/
+    public static final int CAPABILITY_SHARED_SKETCH = (1 << 25);
+    /** Supports communication with Chatbots. */
+    public static final int CAPABILITY_CHAT_BOT = (1 << 26);
+    /** Supports Chatbot roles. */
+    public static final int CAPABILITY_CHAT_BOT_ROLE = (1 << 27);
+    /** Supports the unidirectional plug-ins framework. */
+    public static final int CAPABILITY_PLUG_IN = (1 << 28);
+
 
     /** @hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -110,7 +125,14 @@
             CAPABILITY_GEOLOCATION_PULL_FILE_TRANSFER,
             CAPABILITY_RCS_VOICE_CALL,
             CAPABILITY_RCS_VIDEO_CALL,
-            CAPABILITY_RCS_VIDEO_ONLY_CALL
+            CAPABILITY_RCS_VIDEO_ONLY_CALL,
+            CAPABILITY_CALL_COMPOSER,
+            CAPABILITY_POST_CALL,
+            CAPABILITY_SHARED_MAP,
+            CAPABILITY_SHARED_SKETCH,
+            CAPABILITY_CHAT_BOT,
+            CAPABILITY_CHAT_BOT_ROLE,
+            CAPABILITY_PLUG_IN
     })
     public @interface CapabilityFlag {}
 
@@ -183,7 +205,7 @@
     }
 
     private final Uri mContactUri;
-    private int mCapabilities;
+    private long mCapabilities;
     private List<String> mExtensionTags = new ArrayList<>();
     private Map<Integer, Uri> mServiceMap = new HashMap<>();
 
@@ -198,7 +220,7 @@
 
     private RcsContactUceCapability(Parcel in) {
         mContactUri = in.readParcelable(Uri.class.getClassLoader());
-        mCapabilities = in.readInt();
+        mCapabilities = in.readLong();
         in.readStringList(mExtensionTags);
         // read mServiceMap as key,value pair
         int mapSize = in.readInt();
@@ -223,7 +245,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
         out.writeParcelable(mContactUri, 0);
-        out.writeInt(mCapabilities);
+        out.writeLong(mCapabilities);
         out.writeStringList(mExtensionTags);
         // write mServiceMap as key,value pairs
         int mapSize = mServiceMap.keySet().size();
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index ca081ec..5c86ba7 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -22,8 +22,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
 import android.net.Uri;
 import android.os.Binder;
 import android.telephony.AccessNetworkConstants;
@@ -41,10 +39,7 @@
 
 /**
  * Manages IMS Service registration state for associated {@link ImsFeature}s.
- * @hide
  */
-@SystemApi
-@TestApi
 public interface RegistrationManager {
 
     /**
@@ -157,7 +152,6 @@
                 }
             }
 
-            @Override
             public void onSubscriberAssociatedUriChanged(Uri[] uris) {
                 if (mLocalCallback == null) return;
 
@@ -246,7 +240,11 @@
 
     /**
      * Registers a {@link RegistrationCallback} with the system. Use
-     * {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
+     * @param executor The {@link Executor} that will be used to call the IMS registration state
+     *                 callback.
+     * @param c A callback called on the supplied {@link Executor} that will contain the
+     *                      registration state of the IMS service, which will be one of the
+     * {@see  SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
      * events and call {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up.
      *
      * When the callback is registered, it will initiate the callback c to be called with the
@@ -296,10 +294,10 @@
      * Gets the Transport Type associated with the current IMS registration.
      * @param executor The {@link Executor} that will be used to call the transportTypeCallback.
      * @param transportTypeCallback The transport type associated with the current IMS registration,
- *                              which will be one of following:
- *                              {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN},
- *                              {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, or
- *                              {@link AccessNetworkConstants#TRANSPORT_TYPE_INVALID}.
+     * which will be one of following:
+     * {@see AccessNetworkConstants#TRANSPORT_TYPE_WWAN},
+     * {@see AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, or
+     * {@see AccessNetworkConstants#TRANSPORT_TYPE_INVALID}.
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     void getRegistrationTransportType(
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 4cb8575..e5779b3 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -60,15 +60,21 @@
      * This feature supports emergency calling over MMTEL. If defined, the framework will try to
      * place an emergency call over IMS first. If it is not defined, the framework will only use
      * CSFB for emergency calling.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int FEATURE_EMERGENCY_MMTEL = 0;
     /**
      * This feature supports the MMTEL feature.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int FEATURE_MMTEL = 1;
     /**
      * This feature supports the RCS feature.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int FEATURE_RCS = 2;
     /**
      * Total number of features defined
@@ -116,18 +122,24 @@
      * This {@link ImsFeature}'s state is unavailable and should not be communicated with. This will
      * remove all bindings back to the framework. Any attempt to communicate with the framework
      * during this time will result in an {@link IllegalStateException}.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int STATE_UNAVAILABLE = 0;
     /**
      * This {@link ImsFeature} state is initializing and should not be communicated with. This will
      * remove all bindings back to the framework. Any attempt to communicate with the framework
      * during this time will result in an {@link IllegalStateException}.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int STATE_INITIALIZING = 1;
     /**
      * This {@link ImsFeature} is ready for communication. Do not attempt to call framework methods
-     * until {@link #onFeatureReady()} is called.
+     * until {@see #onFeatureReady()} is called.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int STATE_READY = 2;
 
     /**
@@ -155,11 +167,15 @@
 
     /**
      * The capability was unable to be changed.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int CAPABILITY_ERROR_GENERIC = -1;
     /**
      * The capability was able to be changed.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int CAPABILITY_SUCCESS = 0;
 
     /**
@@ -331,17 +347,20 @@
      *
      * @see SubscriptionManager#getSubscriptionIds(int) for more information on getting the
      * subscription IDs associated with this slot.
+     * @hide
      */
+    @SystemApi @TestApi
     public final int getSlotIndex() {
         return mSlotId;
     }
 
     /**
-     * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE},
-     * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}.
+     * @return The current state of the ImsFeature, set previously by {@link #setFeatureState(int)}
+     * or {@link #STATE_UNAVAILABLE} if it has not been updated  yet.
      * @hide
      */
-    public int getFeatureState() {
+    @SystemApi @TestApi
+    public @ImsState int getFeatureState() {
         synchronized (mLock) {
             return mState;
         }
@@ -352,7 +371,9 @@
      * stop communication, depending on the state sent.
      * @param state The ImsFeature's state, defined as {@link #STATE_UNAVAILABLE},
      * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}.
+     * @hide
      */
+    @SystemApi @TestApi
     public final void setFeatureState(@ImsState int state) {
         synchronized (mLock) {
             if (mState != state) {
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 56c8771..0d5a979 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -52,14 +52,18 @@
  *
  * Any class wishing to use MmTelFeature should extend this class and implement all methods that the
  * service supports.
- * @hide
  */
-@SystemApi
-@TestApi
 public class MmTelFeature extends ImsFeature {
 
     private static final String LOG_TAG = "MmTelFeature";
 
+    /**
+     * @hide
+     */
+    @SystemApi @TestApi
+    public MmTelFeature() {
+    }
+
     private final IImsMmTelFeature mImsMMTelBinder = new IImsMmTelFeature.Stub() {
 
         @Override
@@ -215,11 +219,11 @@
      * {@link MmTelCapabilities#CAPABILITY_TYPE_SMS}.
      *
      * The capabilities of this MmTelFeature will be set by the framework and can be queried with
-     * {@link #queryCapabilityStatus()}.
+     * {@see #queryCapabilityStatus()}.
      *
      * This MmTelFeature can then return the status of each of these capabilities (enabled or not)
-     * by sending a {@link #notifyCapabilitiesStatusChanged} callback to the framework. The current
-     * status can also be queried using {@link #queryCapabilityStatus()}.
+     * by sending a {@see #notifyCapabilitiesStatusChanged} callback to the framework. The current
+     * status can also be queried using {@see #queryCapabilityStatus()}.
      * @see #isCapable(int)
      */
     public static class MmTelCapabilities extends Capabilities {
@@ -228,13 +232,18 @@
          * Create a new empty {@link MmTelCapabilities} instance.
          * @see #addCapabilities(int)
          * @see #removeCapabilities(int)
+         * @hide
          */
+        @SystemApi @TestApi
         public MmTelCapabilities() {
             super();
         }
 
-        /**@deprecated Use {@link MmTelCapabilities} to construct a new instance instead.*/
+        /**@deprecated Use {@link MmTelCapabilities} to construct a new instance instead.
+         * @hide
+         */
         @Deprecated
+        @SystemApi @TestApi
         public MmTelCapabilities(Capabilities c) {
             mCapabilities = c.mCapabilities;
         }
@@ -243,11 +252,17 @@
          * Create a new {link @MmTelCapabilities} instance with the provided capabilities.
          * @param capabilities The capabilities that are supported for MmTel in the form of a
          *                     bitfield.
+         * @hide
          */
+        @SystemApi @TestApi
         public MmTelCapabilities(@MmTelCapability int capabilities) {
             super(capabilities);
         }
 
+        /**
+         * @hide
+         */
+        @SystemApi @TestApi
         @IntDef(flag = true,
                 value = {
                         CAPABILITY_TYPE_VOICE,
@@ -278,23 +293,39 @@
          */
         public static final int CAPABILITY_TYPE_SMS = 1 << 3;
 
+        /**
+        * @hide
+        */
         @Override
+        @SystemApi @TestApi
         public final void addCapabilities(@MmTelCapability int capabilities) {
             super.addCapabilities(capabilities);
         }
 
+        /**
+        * @hide
+        */
         @Override
+        @SystemApi @TestApi
         public final void removeCapabilities(@MmTelCapability int capability) {
             super.removeCapabilities(capability);
         }
 
+        /**
+        * @hide
+        */
         @Override
+        @SystemApi @TestApi
         public final boolean isCapable(@MmTelCapability int capabilities) {
             return super.isCapable(capabilities);
         }
 
+        /**
+        * @hide
+        */
         @NonNull
         @Override
+        @SystemApi @TestApi
         public String toString() {
             StringBuilder builder = new StringBuilder("MmTel Capabilities - [");
             builder.append("Voice: ");
@@ -319,8 +350,10 @@
         /**
          * Called when the IMS provider receives an incoming call.
          * @param c The {@link ImsCallSession} associated with the new call.
+         * @hide
          */
         @Override
+        @SystemApi @TestApi
         public void onIncomingCall(IImsCallSession c, Bundle extras) {
 
         }
@@ -329,8 +362,10 @@
          * Called when the IMS provider implicitly rejects an incoming call during setup.
          * @param callProfile An {@link ImsCallProfile} with the call details.
          * @param reason The {@link ImsReasonInfo} reason for call rejection.
+         * @hide
          */
         @Override
+        @SystemApi @TestApi
         public void onRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) {
 
         }
@@ -338,8 +373,10 @@
         /**
          * Updates the Listener when the voice message count for IMS has changed.
          * @param count an integer representing the new message count.
+         * @hide
          */
         @Override
+        @SystemApi @TestApi
         public void onVoiceMessageCountUpdate(int count) {
 
         }
@@ -348,14 +385,22 @@
     /**
      * To be returned by {@link #shouldProcessCall(String[])} when the ImsService should process the
      * outgoing call as IMS.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int PROCESS_CALL_IMS = 0;
     /**
      * To be returned by {@link #shouldProcessCall(String[])} when the telephony framework should
      * not process the outgoing call as IMS and should instead use circuit switch.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final int PROCESS_CALL_CSFB = 1;
 
+    /**
+    * @hide
+    */
+    @SystemApi @TestApi
     @IntDef(flag = true,
             value = {
                     PROCESS_CALL_IMS,
@@ -368,7 +413,9 @@
      * If the flag is present and true, it indicates that the incoming call is for USSD.
      * <p>
      * This is an optional boolean flag.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
 
     /**
@@ -379,7 +426,9 @@
      * certain situations.
      * <p>
      * This is an optional boolean flag.
+     * @hide
      */
+    @SystemApi @TestApi
     public static final String EXTRA_IS_UNKNOWN_CALL =
             "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
 
@@ -388,6 +437,7 @@
     /**
      * @param listener A {@link Listener} used when the MmTelFeature receives an incoming call and
      *     notifies the framework.
+     * @hide
      */
     private void setListener(IImsMmTelListener listener) {
         synchronized (mLock) {
@@ -406,9 +456,11 @@
      * Should be a subset of the capabilities that are enabled by the framework in
      * {@link #changeEnabledCapabilities}.
      * @return A copy of the current MmTelFeature capability status.
+     * @hide
      */
     @Override
-    public final MmTelCapabilities queryCapabilityStatus() {
+    @SystemApi @TestApi
+    public @NonNull final MmTelCapabilities queryCapabilityStatus() {
         return new MmTelCapabilities(super.queryCapabilityStatus());
     }
 
@@ -420,7 +472,9 @@
      * the status of that capability is disabled. This can happen if the network does not currently
      * support the capability that is enabled. A capability that is disabled by the framework (via
      * {@link #changeEnabledCapabilities}) should also show the status as disabled.
+     * @hide
      */
+    @SystemApi @TestApi
     public final void notifyCapabilitiesStatusChanged(@NonNull MmTelCapabilities c) {
         if (c == null) {
             throw new IllegalArgumentException("MmTelCapabilities must be non-null!");
@@ -433,7 +487,9 @@
      * @param c The {@link ImsCallSessionImplBase} of the new incoming call.
      * @param extras A bundle containing extra parameters related to the call. See
      * {@link #EXTRA_IS_UNKNOWN_CALL} and {@link #EXTRA_IS_USSD} above.
+      * @hide
      */
+    @SystemApi @TestApi
     public final void notifyIncomingCall(@NonNull ImsCallSessionImplBase c,
             @NonNull Bundle extras) {
         if (c == null || extras == null) {
@@ -458,7 +514,9 @@
      * @param callProfile The {@link ImsCallProfile} IMS call profile with details.
      *        This can be null if no call information is available for the rejected call.
      * @param reason The {@link ImsReasonInfo} call rejection reason.
+     * * @hide
      */
+    @SystemApi @TestApi
     public final void notifyRejectedCall(@NonNull ImsCallProfile callProfile,
             @NonNull ImsReasonInfo reason) {
         if (callProfile == null || reason == null) {
@@ -497,7 +555,9 @@
     /**
      * Notify the framework of a change in the Voice Message count.
      * @link count the new Voice Message count.
+     * @hide
      */
+    @SystemApi @TestApi
     public final void notifyVoiceMessageCountUpdate(int count) {
         synchronized (mLock) {
             if (mListener == null) {
@@ -518,8 +578,10 @@
      * status for capability A.
      * @param capability The capability that we are querying the configuration for.
      * @return true if the capability is enabled, false otherwise.
+     * @hide
      */
     @Override
+    @SystemApi @TestApi
     public boolean queryCapabilityConfiguration(@MmTelCapabilities.MmTelCapability int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
         // Base implementation - Override to provide functionality
@@ -537,8 +599,10 @@
      * Enabling/Disabling a capability here indicates that the capability should be registered or
      * deregistered (depending on the capability change) and become available or unavailable to
      * the framework.
+     * * @hide
      */
     @Override
+    @SystemApi @TestApi
     public void changeEnabledCapabilities(@NonNull CapabilityChangeRequest request,
             @NonNull CapabilityCallbackProxy c) {
         // Base implementation, no-op
@@ -561,7 +625,9 @@
      *        {@link ImsCallProfile#CALL_TYPE_VS_TX}
      *        {@link ImsCallProfile#CALL_TYPE_VS_RX}
      * @return a {@link ImsCallProfile} object
+     * @hide
      */
+    @SystemApi @TestApi
     public @Nullable ImsCallProfile createCallProfile(int callSessionType, int callType) {
         // Base Implementation - Should be overridden
         return null;
@@ -582,7 +648,9 @@
      * {@link ImsCallSession} directly.
      *
      * @param profile a call profile to make the call
+     * @hide
      */
+    @SystemApi @TestApi
     public @Nullable ImsCallSessionImplBase createCallSession(@NonNull ImsCallProfile profile) {
         // Base Implementation - Should be overridden
         return null;
@@ -599,7 +667,9 @@
      *         call as a conference.
      * @return a {@link ProcessCallResult} to the framework, which will be used to determine if the
      *        call will be placed over IMS or via CSFB.
+     * @hide
      */
+    @SystemApi @TestApi
     public @ProcessCallResult int shouldProcessCall(@NonNull String[] numbers) {
         return PROCESS_CALL_IMS;
     }
@@ -632,7 +702,9 @@
     /**
      * @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service
      * configuration.
+     * @hide
      */
+    @SystemApi @TestApi
     public @NonNull ImsUtImplBase getUt() {
         // Base Implementation - Should be overridden
         return new ImsUtImplBase();
@@ -641,7 +713,9 @@
     /**
      * @return The {@link ImsEcbmImplBase} Emergency call-back mode interface for emergency VoLTE
      * calls that support it.
+     * @hide
      */
+    @SystemApi @TestApi
     public @NonNull ImsEcbmImplBase getEcbm() {
         // Base Implementation - Should be overridden
         return new ImsEcbmImplBase();
@@ -650,7 +724,9 @@
     /**
      * @return The {@link ImsMultiEndpointImplBase} implementation for implementing Dialog event
      * package processing for multi-endpoint.
+     * @hide
      */
+    @SystemApi @TestApi
     public @NonNull ImsMultiEndpointImplBase getMultiEndpoint() {
         // Base Implementation - Should be overridden
         return new ImsMultiEndpointImplBase();
@@ -676,7 +752,9 @@
      *         // Remote side is dead
      *     }
      * }
+     * @hide
      */
+    @SystemApi @TestApi
     public void setUiTtyMode(int mode, @Nullable Message onCompleteMessage) {
         // Base Implementation - Should be overridden
     }
@@ -710,7 +788,9 @@
      *
      * @return an instance of {@link ImsSmsImplBase} which should be implemented by the IMS
      * Provider.
+     * @hide
      */
+    @SystemApi @TestApi
     public @NonNull ImsSmsImplBase getSmsImplementation() {
         return new ImsSmsImplBase();
     }
@@ -719,14 +799,22 @@
         return getSmsImplementation().getSmsFormat();
     }
 
-    /**{@inheritDoc}*/
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
     @Override
+    @SystemApi @TestApi
     public void onFeatureRemoved() {
         // Base Implementation - Should be overridden
     }
 
-    /**{@inheritDoc}*/
+    /**
+     * {@inheritDoc}
+     * @hide
+     */
     @Override
+    @SystemApi @TestApi
     public void onFeatureReady() {
         // Base Implementation - Should be overridden
     }
diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
index feac3c2..3ec4f34 100644
--- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
@@ -16,6 +16,7 @@
 
 package android.telephony.ims.stub;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.Bundle;
@@ -25,6 +26,9 @@
 import com.android.ims.internal.IImsUt;
 import com.android.ims.internal.IImsUtListener;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Base implementation of IMS UT interface, which implements stubs. Override these methods to
  * implement functionality.
@@ -36,6 +40,70 @@
 @SystemApi
 @TestApi
 public class ImsUtImplBase {
+    /**
+     * Bar all incoming calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ALL_INCOMING = 1;
+
+    /**
+     * Bar all outgoing calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ALL_OUTGOING = 2;
+
+    /**
+     * Bar all outgoing international calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_OUTGOING_INTL = 3;
+
+    /**
+     * Bar all outgoing international calls, excluding those to the home PLMN country
+     * (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4;
+
+    /**
+     * Bar all incoming calls when roaming (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5;
+
+    /**
+     * Enable Anonymous Communication Rejection (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6;
+
+    /**
+     * Bar all incoming and outgoing calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ALL = 7;
+
+    /**
+     * Bar all outgoing service requests, including calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8;
+
+    /**
+     * Bar all incoming service requests, including calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9;
+
+    /**
+     * Bar specific incoming calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CALL_BARRING_", value = {CALL_BARRING_ALL_INCOMING, CALL_BARRING_ALL_OUTGOING,
+            CALL_BARRING_OUTGOING_INTL, CALL_BARRING_OUTGOING_INTL_EXCL_HOME,
+            CALL_BLOCKING_INCOMING_WHEN_ROAMING, CALL_BARRING_ANONYMOUS_INCOMING,
+            CALL_BARRING_ALL, CALL_BARRING_OUTGOING_ALL_SERVICES,
+            CALL_BARRING_INCOMING_ALL_SERVICES, CALL_BARRING_SPECIFIC_INCOMING_CALLS})
+    public @interface CallBarringMode {}
+
+    /**
+     * Constant used to denote an invalid return value.
+     */
+    public static final int INVALID_RESULT = -1;
 
     private IImsUt.Stub mServiceImpl = new IImsUt.Stub() {
         @Override
@@ -247,15 +315,15 @@
     /**
      * Updates the configuration of the call barring.
      */
-    public int updateCallBarring(int cbType, int action, String[] barrList) {
+    public int updateCallBarring(@CallBarringMode int cbType, int action, String[] barrList) {
         return -1;
     }
 
     /**
      * Updates the configuration of the call barring for specified service class.
      */
-    public int updateCallBarringForServiceClass(int cbType, int action, String[] barrList,
-            int serviceClass) {
+    public int updateCallBarringForServiceClass(@CallBarringMode int cbType, int action,
+            String[] barrList, int serviceClass) {
         return -1;
     }
 
diff --git a/telephony/java/com/android/ims/ImsUtInterface.java b/telephony/java/com/android/ims/ImsUtInterface.java
index 50b63bd..15f8371 100644
--- a/telephony/java/com/android/ims/ImsUtInterface.java
+++ b/telephony/java/com/android/ims/ImsUtInterface.java
@@ -21,6 +21,7 @@
 import android.os.Message;
 import android.telephony.ims.ImsCallForwardInfo;
 import android.telephony.ims.ImsSsInfo;
+import android.telephony.ims.stub.ImsUtImplBase;
 
 /**
  * Provides APIs for the supplementary service settings using IMS (Ut interface).
@@ -58,47 +59,48 @@
      * CDIV (Communication Diversion, 3GPP TS 24.604)
      *     actions: target, no reply timer
      */
-    public static final int CDIV_CF_UNCONDITIONAL = 0;
-    public static final int CDIV_CF_BUSY = 1;
-    public static final int CDIV_CF_NO_REPLY = 2;
-    public static final int CDIV_CF_NOT_REACHABLE = 3;
+    public static final int CDIV_CF_UNCONDITIONAL = ImsCallForwardInfo.CDIV_CF_REASON_UNCONDITIONAL;
+    public static final int CDIV_CF_BUSY = ImsCallForwardInfo.CDIV_CF_REASON_BUSY;
+    public static final int CDIV_CF_NO_REPLY = ImsCallForwardInfo.CDIV_CF_REASON_NO_REPLY;
+    public static final int CDIV_CF_NOT_REACHABLE = ImsCallForwardInfo.CDIV_CF_REASON_NOT_REACHABLE;
     // For CS service code: 002
-    public static final int CDIV_CF_ALL = 4;
+    public static final int CDIV_CF_ALL = ImsCallForwardInfo.CDIV_CF_REASON_ALL;
     // For CS service code: 004
-    public static final int CDIV_CF_ALL_CONDITIONAL = 5;
+    public static final int CDIV_CF_ALL_CONDITIONAL =
+            ImsCallForwardInfo.CDIV_CF_REASON_ALL_CONDITIONAL;
     // It's only supported in the IMS service (CS does not define it).
     // IR.92 recommends that an UE activates both the CFNRc and the CFNL
     // (CDIV using condition not-registered) to the same target.
-    public static final int CDIV_CF_NOT_LOGGED_IN = 6;
+    public static final int CDIV_CF_NOT_LOGGED_IN = ImsCallForwardInfo.CDIV_CF_REASON_NOT_LOGGED_IN;
 
     /**
      * CB (Communication Barring, 3GPP TS 24.611)
      */
     // Barring of All Incoming Calls
-    public static final int CB_BAIC = 1;
+    public static final int CB_BAIC = ImsUtImplBase.CALL_BARRING_ALL_INCOMING;
     // Barring of All Outgoing Calls
-    public static final int CB_BAOC = 2;
+    public static final int CB_BAOC = ImsUtImplBase.CALL_BARRING_ALL_OUTGOING;
     // Barring of Outgoing International Calls
-    public static final int CB_BOIC = 3;
+    public static final int CB_BOIC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL;
     // Barring of Outgoing International Calls - excluding Home Country
-    public static final int CB_BOIC_EXHC = 4;
+    public static final int CB_BOIC_EXHC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL_EXCL_HOME;
     // Barring of Incoming Calls - when roaming
-    public static final int CB_BIC_WR = 5;
+    public static final int CB_BIC_WR = ImsUtImplBase.CALL_BLOCKING_INCOMING_WHEN_ROAMING;
     // Barring of Anonymous Communication Rejection (ACR) - a particular case of ICB service
-    public static final int CB_BIC_ACR = 6;
+    public static final int CB_BIC_ACR = ImsUtImplBase.CALL_BARRING_ANONYMOUS_INCOMING;
     // Barring of All Calls
-    public static final int CB_BA_ALL = 7;
+    public static final int CB_BA_ALL = ImsUtImplBase.CALL_BARRING_ALL;
     // Barring of Outgoing Services (Service Code 333 - 3GPP TS 22.030 Table B-1)
-    public static final int CB_BA_MO = 8;
+    public static final int CB_BA_MO = ImsUtImplBase.CALL_BARRING_OUTGOING_ALL_SERVICES;
     // Barring of Incoming Services (Service Code 353 - 3GPP TS 22.030 Table B-1)
-    public static final int CB_BA_MT = 9;
+    public static final int CB_BA_MT = ImsUtImplBase.CALL_BARRING_INCOMING_ALL_SERVICES;
     // Barring of Specific Incoming calls
-    public static final int CB_BS_MT = 10;
+    public static final int CB_BS_MT = ImsUtImplBase.CALL_BARRING_SPECIFIC_INCOMING_CALLS;
 
     /**
      * Invalid result value.
      */
-    public static final int INVALID = (-1);
+    public static final int INVALID = ImsUtImplBase.INVALID_RESULT;
 
 
 
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c07a171..79cdce8 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -145,10 +145,13 @@
      *   be automatically persisted in the SMS db. It only affects messages sent
      *   by a non-default SMS app. Currently only the carrier app can set this
      *   parameter to false to skip auto message persistence.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     *   Used for logging and diagnostics purposes. The id may be 0.
      */
     void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr,
             in String scAddr, in String text, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp);
+            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
+            in long messageId);
 
     /**
      * Send an SMS. Internal use only.
@@ -270,11 +273,14 @@
      *   be automatically persisted in the SMS db. It only affects messages sent
      *   by a non-default SMS app. Currently only the carrier app can set this
      *   parameter to false to skip auto message persistence.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     *   Used for logging and diagnostics purposes. The id may be 0.
      */
     void sendMultipartTextForSubscriber(in int subId, String callingPkg,
             in String destinationAddress, in String scAddress,
             in List<String> parts, in List<PendingIntent> sentIntents,
-            in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp);
+            in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp,
+            in long messageId);
 
     /**
      * Send a multi-part text based SMS with options using Subscription Id.
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index ddd3457..db0b8e5 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -61,7 +61,8 @@
     @Override
     public void sendTextForSubscriber(int subId, String callingPkg, String destAddr,
             String scAddr, String text, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) {
+            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp,
+            long messageId) {
         throw new UnsupportedOperationException();
     }
 
@@ -90,7 +91,8 @@
     public void sendMultipartTextForSubscriber(int subId, String callingPkg,
             String destinationAddress, String scAddress,
             List<String> parts, List<PendingIntent> sentIntents,
-            List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) {
+            List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
+            long messageId) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index a8e76b9..7add741 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -922,6 +922,23 @@
             int subId, in OperatorInfo operatorInfo, boolean persisSelection);
 
     /**
+     * Get the allowed network types that store in the telephony provider.
+     *
+     * @param subId the id of the subscription.
+     * @return allowedNetworkTypes the allowed network types.
+     */
+    long getAllowedNetworkTypes(int subId);
+
+    /**
+     * Set the allowed network types.
+     *
+     * @param subId the id of the subscription.
+     * @param allowedNetworkTypes the allowed network types.
+     * @return true on success; false on any failure.
+     */
+    boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes);
+
+    /**
      * Set the preferred network type.
      * Used for device configuration by some CDMA operators.
      *
@@ -2147,4 +2164,10 @@
      * Notify Rcs auto config received.
      */
     void notifyRcsAutoConfigurationReceived(int subId, in byte[] config, boolean isCompressed);
+
+    boolean isIccLockEnabled(int subId);
+
+    int setIccLockEnabled(int subId, boolean enabled, String password);
+
+    int changeIccLockPassword(int subId, String oldPassword, String newPassword);
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index db8c845..4d67754 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -16,6 +16,7 @@
 package com.android.internal.telephony;
 
 import android.compat.annotation.UnsupportedAppUsage;
+import android.telephony.data.ApnSetting;
 
 /**
  * @hide
@@ -125,32 +126,32 @@
      * APN_TYPE_ALL is a special type to indicate that this APN entry can
      * service all data connections.
      */
-    public static final String APN_TYPE_ALL = "*";
+    public static final String APN_TYPE_ALL = ApnSetting.TYPE_ALL_STRING;
     /** APN type for default data traffic */
-    public static final String APN_TYPE_DEFAULT = "default";
+    public static final String APN_TYPE_DEFAULT = ApnSetting.TYPE_DEFAULT_STRING;
     /** APN type for MMS traffic */
-    public static final String APN_TYPE_MMS = "mms";
+    public static final String APN_TYPE_MMS = ApnSetting.TYPE_MMS_STRING;
     /** APN type for SUPL assisted GPS */
-    public static final String APN_TYPE_SUPL = "supl";
+    public static final String APN_TYPE_SUPL = ApnSetting.TYPE_SUPL_STRING;
     /** APN type for DUN traffic */
-    public static final String APN_TYPE_DUN = "dun";
+    public static final String APN_TYPE_DUN = ApnSetting.TYPE_DUN_STRING;
     /** APN type for HiPri traffic */
-    public static final String APN_TYPE_HIPRI = "hipri";
+    public static final String APN_TYPE_HIPRI = ApnSetting.TYPE_HIPRI_STRING;
     /** APN type for FOTA */
-    public static final String APN_TYPE_FOTA = "fota";
+    public static final String APN_TYPE_FOTA = ApnSetting.TYPE_FOTA_STRING;
     /** APN type for IMS */
-    public static final String APN_TYPE_IMS = "ims";
+    public static final String APN_TYPE_IMS = ApnSetting.TYPE_IMS_STRING;
     /** APN type for CBS */
-    public static final String APN_TYPE_CBS = "cbs";
+    public static final String APN_TYPE_CBS = ApnSetting.TYPE_CBS_STRING;
     /** APN type for IA Initial Attach APN */
-    public static final String APN_TYPE_IA = "ia";
+    public static final String APN_TYPE_IA = ApnSetting.TYPE_IA_STRING;
     /** APN type for Emergency PDN. This is not an IA apn, but is used
      * for access to carrier services in an emergency call situation. */
-    public static final String APN_TYPE_EMERGENCY = "emergency";
+    public static final String APN_TYPE_EMERGENCY = ApnSetting.TYPE_EMERGENCY_STRING;
     /** APN type for Mission Critical Services */
-    public static final String APN_TYPE_MCX = "mcx";
+    public static final String APN_TYPE_MCX = ApnSetting.TYPE_MCX_STRING;
     /** APN type for XCAP */
-    public static final String APN_TYPE_XCAP = "xcap";
+    public static final String APN_TYPE_XCAP = ApnSetting.TYPE_XCAP_STRING;
     /** Array of all APN types */
     public static final String[] APN_TYPES = {APN_TYPE_DEFAULT,
             APN_TYPE_MMS,
diff --git a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
index b8b2de5..f3c89d8a 100644
--- a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
+++ b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
@@ -97,6 +97,11 @@
         mRoot.setWindowInsetsAnimationCallback(new WindowInsetsAnimationCallback() {
 
             @Override
+            public int getDispatchMode() {
+                return DISPATCH_MODE_STOP;
+            }
+
+            @Override
             public void onPrepare(InsetsAnimation animation) {
                 if ((animation.getTypeMask() & Type.ime()) != 0) {
                     imeAnim = animation;
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
new file mode 100644
index 0000000..d250ad3
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.assertParcelSane
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkAgentConfigTest {
+    @Test
+    fun testParcelNetworkAgentConfig() {
+        val config = NetworkAgentConfig.Builder().apply {
+            setExplicitlySelected(true)
+            setLegacyType(ConnectivityManager.TYPE_ETHERNET)
+            setSubscriberId("MySubId")
+            setPartialConnectivityAcceptable(false)
+            setUnvalidatedConnectivityAcceptable(true)
+        }.build()
+        assertParcelSane(config, 9)
+    }
+}
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 1c69209..a35fb40 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -222,7 +222,7 @@
 
     @Override
     public Network getNetwork() {
-        return mNetworkAgent.network;
+        return mNetworkAgent.getNetwork();
     }
 
     public void expectPreventReconnectReceived(long timeoutMs) {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1901a1d..4e29334 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -575,7 +575,7 @@
                 }
             };
 
-            assertEquals(na.network.netId, nmNetworkCaptor.getValue().netId);
+            assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
             mNmCallbacks = nmCbCaptor.getValue();
 
             mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 7bbac13..d290aca 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -443,7 +443,7 @@
     AtomDecl nonChainedAtomDecl(atomField->number(), atomField->name(), atom->name());
     vector<java_type_t> nonChainedSignature;
     if (get_non_chained_node(atom, &nonChainedAtomDecl, &nonChainedSignature)) {
-        auto it = atoms->non_chained_signatures_to_modules.find(signature);
+        auto it = atoms->non_chained_signatures_to_modules.find(nonChainedSignature);
         if (it == atoms->non_chained_signatures_to_modules.end()) {
             set<string> modules_non_chained;
             if (atomDecl.hasModule) {
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
index b09dcd5..c29936b 100644
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ b/tools/stats_log_api_gen/java_writer.cpp
@@ -73,7 +73,7 @@
                         java_type_name(chainField.javaType), chainField.name.c_str());
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", SparseArray<Object> valueMap");
+                fprintf(out, ", android.util.SparseArray<Object> valueMap");
             } else {
                 fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
             }
@@ -142,16 +142,16 @@
                 fprintf(out,
                         "%s        final int count = valueMap.size();\n", indent.c_str());
                 fprintf(out,
-                        "%s        SparseIntArray intMap = null;\n",
+                        "%s        android.util.SparseIntArray intMap = null;\n",
                         indent.c_str());
                 fprintf(out,
-                        "%s        SparseLongArray longMap = null;\n",
+                        "%s        android.util.SparseLongArray longMap = null;\n",
                         indent.c_str());
                 fprintf(out,
-                        "%s        SparseArray<String> stringMap = null;\n",
+                        "%s        android.util.SparseArray<String> stringMap = null;\n",
                         indent.c_str());
                 fprintf(out,
-                        "%s        SparseArray<Float> floatMap = null;\n",
+                        "%s        android.util.SparseArray<Float> floatMap = null;\n",
                         indent.c_str());
                 fprintf(out,
                         "%s        for (int i = 0; i < count; i++) {\n", indent.c_str());
@@ -165,7 +165,7 @@
                 fprintf(out,
                         "%s                if (null == intMap) {\n", indent.c_str());
                 fprintf(out,
-                        "%s                    intMap = new SparseIntArray();\n", indent.c_str());
+                        "%s                    intMap = new android.util.SparseIntArray();\n", indent.c_str());
                 fprintf(out,
                         "%s                }\n", indent.c_str());
                 fprintf(out,
@@ -175,7 +175,7 @@
                 fprintf(out,
                         "%s                if (null == longMap) {\n", indent.c_str());
                 fprintf(out,
-                        "%s                    longMap = new SparseLongArray();\n", indent.c_str());
+                        "%s                    longMap = new android.util.SparseLongArray();\n", indent.c_str());
                 fprintf(out,
                         "%s                }\n", indent.c_str());
                 fprintf(out,
@@ -185,7 +185,7 @@
                 fprintf(out,
                         "%s                if (null == stringMap) {\n", indent.c_str());
                 fprintf(out,
-                        "%s                    stringMap = new SparseArray<>();\n", indent.c_str());
+                        "%s                    stringMap = new android.util.SparseArray<>();\n", indent.c_str());
                 fprintf(out,
                         "%s                }\n", indent.c_str());
                 fprintf(out,
@@ -195,7 +195,7 @@
                 fprintf(out,
                         "%s                if (null == floatMap) {\n", indent.c_str());
                 fprintf(out,
-                        "%s                    floatMap = new SparseArray<>();\n", indent.c_str());
+                        "%s                    floatMap = new android.util.SparseArray<>();\n", indent.c_str());
                 fprintf(out,
                         "%s                }\n", indent.c_str());
                 fprintf(out,
@@ -253,7 +253,8 @@
 
 int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
                                     const string& moduleName, const string& javaClass,
-                                    const string& javaPackage, const bool supportQ) {
+                                    const string& javaPackage, const bool supportQ,
+                                    const bool supportWorkSource) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
@@ -265,25 +266,9 @@
         fprintf(out, "import android.os.SystemClock;\n");
     }
 
-    if (DEFAULT_MODULE_NAME == moduleName) {
-        // Mainline modules don't use WorkSource logging.
-        fprintf(out, "import android.os.WorkSource;\n");
-
-        // SparseArray is used for writing KeyValuePairs; not supported for Mainline modules.
-        fprintf(out, "import android.util.SparseArray;\n");
-        fprintf(out, "import android.util.SparseIntArray;\n");
-        fprintf(out, "import android.util.SparseLongArray;\n");
-    }
-
     fprintf(out, "import android.util.StatsEvent;\n");
     fprintf(out, "import android.util.StatsLog;\n");
 
-    if (DEFAULT_MODULE_NAME == moduleName) {
-        // List is used for WorkSource writing. Only needed for default module.
-        fprintf(out, "\n");
-        fprintf(out, "import java.util.List;\n");
-    }
-
     fprintf(out, "\n");
     fprintf(out, "\n");
     fprintf(out, "/**\n");
@@ -305,7 +290,7 @@
             out, atoms.signatures_to_modules, attributionDecl, moduleName, supportQ);
     errors += write_java_non_chained_methods(
             out, atoms.non_chained_signatures_to_modules, moduleName);
-    if (DEFAULT_MODULE_NAME == moduleName) {
+    if (supportWorkSource) {
         errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
     }
 
diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h
index 9324b23..5b78f05 100644
--- a/tools/stats_log_api_gen/java_writer.h
+++ b/tools/stats_log_api_gen/java_writer.h
@@ -31,8 +31,9 @@
 using namespace std;
 
 int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
-                                    const string& moduleName, const string& javaClass,
-                                    const string& javaPackage, const bool supportQ);
+                         const string& moduleName, const string& javaClass,
+                         const string& javaPackage, const bool supportQ,
+                         const bool supportWorkSource);
 
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
index af5055a..f866129 100644
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ b/tools/stats_log_api_gen/java_writer_q.cpp
@@ -382,7 +382,7 @@
                         java_type_name(chainField.javaType), chainField.name.c_str());
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", SparseArray<Object> value_map");
+                fprintf(out, ", android.util.SparseArray<Object> value_map");
             } else {
                 fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
             }
@@ -393,16 +393,13 @@
     }
 }
 
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) {
+int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+                           const bool supportWorkSource) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
     fprintf(out, "package android.util;\n");
     fprintf(out, "\n");
-    fprintf(out, "import android.os.WorkSource;\n");
-    fprintf(out, "import android.util.SparseArray;\n");
-    fprintf(out, "import java.util.List;\n");
-    fprintf(out, "\n");
     fprintf(out, "\n");
     fprintf(out, "/**\n");
     fprintf(out, " * API For logging statistics events.\n");
@@ -418,16 +415,19 @@
     write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
     write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
             attributionDecl);
-    write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
+    if (supportWorkSource) {
+        write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
+    }
 
     fprintf(out, "}\n");
 
     return 0;
 }
 
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
-                                    const string& moduleName, const string& javaClass,
-                                    const string& javaPackage) {
+int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
+                                      const AtomDecl &attributionDecl, const string& moduleName,
+                                      const string& javaClass, const string& javaPackage,
+                                      const bool supportWorkSource) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
@@ -438,8 +438,6 @@
     fprintf(out, "import android.util.StatsLog;\n");
     fprintf(out, "import android.os.SystemClock;\n");
     fprintf(out, "\n");
-    fprintf(out, "import java.util.ArrayList;\n");
-    fprintf(out, "\n");
     fprintf(out, "\n");
     fprintf(out, "/**\n");
     fprintf(out, " * Utility class for logging statistics events.\n");
@@ -459,6 +457,9 @@
             moduleName, "    ");
     errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules,
             moduleName);
+    if (supportWorkSource) {
+        errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
+    }
 
     fprintf(out, "}\n");
 
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
index 96ac745..36df1d8 100644
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ b/tools/stats_log_api_gen/java_writer_q.h
@@ -46,11 +46,12 @@
         const string& indent);
 
 #if defined(STATS_SCHEMA_LEGACY)
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl);
+int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+                           const bool supportWorkSource);
 
 int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
         const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass,
-        const string& javaPackage);
+        const string& javaPackage, const bool supportWorkSource);
 #endif
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 00a3704..6089532 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -512,6 +512,7 @@
     fprintf(stderr, "                       Optional for Java with module.\n");
     fprintf(stderr, "                       Default is \"StatsLogInternal\"\n");
     fprintf(stderr, "  --supportQ           Include support for Android Q.\n");
+    fprintf(stderr, "  --worksource         Include support for logging WorkSource objects.\n");
 }
 
 /**
@@ -534,6 +535,7 @@
     string javaPackage = DEFAULT_JAVA_PACKAGE;
     string javaClass = DEFAULT_JAVA_CLASS;
     bool supportQ = false;
+    bool supportWorkSource = false;
 
     int index = 1;
     while (index < argc) {
@@ -626,6 +628,8 @@
             atomsInfoCppHeaderImport = argv[index];
         } else if (0 == strcmp("--supportQ", argv[index])) {
             supportQ = true;
+        } else if (0 == strcmp("--worksource", argv[index])) {
+            supportWorkSource = true;
         }
 
         index++;
@@ -728,19 +732,15 @@
             fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
             return 1;
         }
-        // If this is for a specific module, the java package must also be provided.
-        if (moduleName != DEFAULT_MODULE_NAME && javaPackage== DEFAULT_JAVA_PACKAGE) {
-            fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n");
-            return 1;
-        }
 
 #if defined(STATS_SCHEMA_LEGACY)
         if (moduleName == DEFAULT_MODULE_NAME) {
             errorCount = android::stats_log_api_gen::write_stats_log_java_q(
-                    out, atoms, attributionDecl);
+                    out, atoms, attributionDecl, supportWorkSource);
         } else {
             errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
-                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage);
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage,
+                    supportWorkSource);
 
         }
 #else
@@ -749,7 +749,8 @@
             javaPackage = "android.util";
         }
         errorCount = android::stats_log_api_gen::write_stats_log_java(
-                out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ);
+                out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ,
+                supportWorkSource);
 #endif
 
         fclose(out);
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
index c65d190..8c4abe4 100644
--- a/tools/stats_log_api_gen/utils.cpp
+++ b/tools/stats_log_api_gen/utils.cpp
@@ -334,7 +334,7 @@
         if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
             fprintf(out, ", android.os.WorkSource workSource");
         } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
-            fprintf(out, ", SparseArray<Object> value_map");
+            fprintf(out, ", android.util.SparseArray<Object> value_map");
         } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
             fprintf(out, ", byte[] %s", field->name.c_str());
         } else {
@@ -442,7 +442,7 @@
         for (vector<java_type_t>::const_iterator arg = signature.begin();
                 arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
-                fprintf(out, ", WorkSource ws");
+                fprintf(out, ", android.os.WorkSource ws");
             } else {
                 fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
             }
@@ -464,9 +464,10 @@
         fprintf(out, "        }\n"); // close for-loop
 
         // write() component.
-        fprintf(out, "        List<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
+        fprintf(out, "        java.util.List<android.os.WorkSource.WorkChain> workChains = "
+                "ws.getWorkChains();\n");
         fprintf(out, "        if (workChains != null) {\n");
-        fprintf(out, "            for (WorkSource.WorkChain wc : workChains) {\n");
+        fprintf(out, "            for (android.os.WorkSource.WorkChain wc : workChains) {\n");
         fprintf(out, "                write(code");
         for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
             if (argIndex == attributionArg) {
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 4c9ee85..099cbff 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -58,19 +58,20 @@
 // classes before they are renamed.
 java_library {
     name: "framework-wifi-pre-jarjar",
-    // TODO(b/140299412) should be core_current once we build against framework-system-stubs
-    sdk_version: "core_platform",
+    // TODO(b/146757305): sdk_version should be "module_lib_current"
+    sdk_version: "core_current",
     static_libs: [
         "framework-wifi-util-lib",
         "android.hardware.wifi-V1.0-java-constants",
     ],
     libs: [
-        // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies
-        "framework-minus-apex",
         "framework-annotations-lib",
         "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
         "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage
         "framework-telephony-stubs",
+        // TODO(b/146757305): should be unnecessary once
+        // sdk_version="module_lib_current"
+        "android_system_stubs_current",
     ],
     srcs: [
         ":framework-wifi-updatable-sources",
@@ -80,13 +81,21 @@
         "//frameworks/opt/net/wifi/service",
         "//frameworks/opt/net/wifi/tests/wifitests",
     ],
+
+    // TODO(b/146757305): should be unnecessary once
+    // sdk_version="module_lib_current"
+    aidl: {
+        include_dirs: [
+            "frameworks/base/core/java",
+        ],
+    },
 }
 
 // post-jarjar version of framework-wifi
 java_library {
     name: "framework-wifi",
-    // TODO(b/140299412) should be core_current once we build against framework-system-stubs
-    sdk_version: "core_platform",
+    // TODO(b/146757305): sdk_version should be "module_lib_current"
+    sdk_version: "core_current",
     static_libs: [
         "framework-wifi-pre-jarjar",
     ],
@@ -98,7 +107,6 @@
     },
     hostdex: true, // for hiddenapi check
     visibility: [
-        "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed
         "//frameworks/opt/net/wifi/service:__subpackages__",
     ] + test_access_hidden_api_whitelist,
     apex_available: [
@@ -114,6 +122,8 @@
         ":framework-annotations",
         ":framework-wifi-updatable-sources",
     ],
+    // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on
+    // WifiActivityEnergyInfo.aidl in framework-minus-apex
     aidl: {
         include_dirs: ["frameworks/base/core/java"],
     },
@@ -125,11 +135,6 @@
 java_library {
     name: "framework-wifi-stubs",
     srcs: [":framework-wifi-stubs-srcs"],
-    aidl: {
-        export_include_dirs: [
-            "java",
-        ],
-    },
     sdk_version: "core_current",
     libs: ["android_system_stubs_current"],
     installable: false,
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index d377ee6..950361c 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -35,6 +35,7 @@
 rule android.content.pm.ParceledListSlice* android.x.net.wifi.util.ParceledListSlice@1
 rule android.net.shared.Inet4AddressUtils* android.x.net.wifi.util.Inet4AddressUtils@1
 rule android.net.util.MacAddressUtils* android.x.net.wifi.util.MacAddressUtils@1
+rule android.net.util.nsd.DnsSdTxtRecord* android.x.net.wifi.util.nsd.DnsSdTxtRecord@1
 rule android.os.HandlerExecutor* android.x.net.wifi.util.HandlerExecutor@1
 rule android.telephony.Annotation* android.x.net.wifi.util.TelephonyAnnotation@1
 rule com.android.internal.util.AsyncChannel* android.x.net.wifi.util.AsyncChannel@1
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
index b83b594..b567f29 100644
--- a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
+++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
@@ -16,7 +16,7 @@
 
 package android.net.wifi;
 
-import android.net.wifi.WifiConfiguration;
+import android.net.wifi.SoftApConfiguration;
 
 /**
  * Communicates LOHS status back to the application process.
@@ -24,7 +24,7 @@
  * @hide
  */
 oneway interface ILocalOnlyHotspotCallback {
-    void onHotspotStarted(in WifiConfiguration config);
+    void onHotspotStarted(in SoftApConfiguration config);
     void onHotspotStopped();
     void onHotspotFailed(int reason);
 }
diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
index d14ec57..51d74f0 100644
--- a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
+++ b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
@@ -17,7 +17,6 @@
 package android.net.wifi;
 
 import android.net.wifi.INetworkRequestUserSelectionCallback;
-import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 
 /**
@@ -31,7 +30,7 @@
 
    void onAbort();
 
-   void onMatch(in List<ScanResult> scanResults);
+   void onMatch(in List<android.net.wifi.ScanResult> scanResults);
 
    void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration);
 
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendCallback.java b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
similarity index 72%
rename from media/java/android/media/tv/tuner/frontend/FrontendCallback.java
rename to wifi/java/android/net/wifi/IScoreChangeCallback.aidl
index 9c4f460..fd23610 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendCallback.java
+++ b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl
@@ -14,17 +14,16 @@
  * limitations under the License.
  */
 
-package android.media.tv.tuner.frontend;
+package android.net.wifi;
 
 /**
- * Frontend Callback.
+ * Interface for Wi-Fi network score callback.
  *
  * @hide
  */
-public interface FrontendCallback {
+oneway interface IScoreChangeCallback
+{
+    void onStatusChange(int sessionId, boolean exiting);
 
-    /**
-     * Invoked when there is a frontend event.
-     */
-    void onEvent(int frontendEventType);
+    void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
 }
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendCallback.java b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
similarity index 68%
copy from media/java/android/media/tv/tuner/frontend/FrontendCallback.java
copy to wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
index 9c4f460..d9a3b01 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendCallback.java
+++ b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl
@@ -14,17 +14,20 @@
  * limitations under the License.
  */
 
-package android.media.tv.tuner.frontend;
+package android.net.wifi;
+
+import android.net.wifi.IScoreChangeCallback;
 
 /**
- * Frontend Callback.
+ * Interface for Wi-Fi connected network scorer.
  *
  * @hide
  */
-public interface FrontendCallback {
+oneway interface IWifiConnectedNetworkScorer
+{
+    void start(int sessionId);
 
-    /**
-     * Invoked when there is a frontend event.
-     */
-    void onEvent(int frontendEventType);
+    void stop(int sessionId);
+
+    void setScoreChangeCallback(IScoreChangeCallback cbImpl);
 }
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 67f1663..0b5969a 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -35,7 +35,7 @@
 import android.net.wifi.ISuggestionConnectionStatusListener;
 import android.net.wifi.ITrafficStateCallback;
 import android.net.wifi.ITxPacketCountListener;
-import android.net.wifi.ScanResult;
+import android.net.wifi.IWifiConnectedNetworkScorer;
 import android.net.wifi.SoftApConfiguration;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
@@ -60,9 +60,9 @@
 
     ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId);
 
-    Map getAllMatchingFqdnsForScanResults(in List<ScanResult> scanResult);
+    Map getAllMatchingFqdnsForScanResults(in List<android.net.wifi.ScanResult> scanResult);
 
-    Map getMatchingOsuProviders(in List<ScanResult> scanResult);
+    Map getMatchingOsuProviders(in List<android.net.wifi.ScanResult> scanResult);
 
     Map getMatchingPasspointConfigsForOsuProviders(in List<OsuProvider> osuProviders);
 
@@ -96,7 +96,7 @@
 
     boolean startScan(String packageName, String featureId);
 
-    List<ScanResult> getScanResults(String callingPackage, String callingFeatureId);
+    List<android.net.wifi.ScanResult> getScanResults(String callingPackage, String callingFeatureId);
 
     boolean disconnect(String packageName);
 
@@ -116,6 +116,8 @@
 
     boolean is6GHzBandSupported();
 
+    boolean isWifiStandardSupported(int standard);
+
     boolean needs5GHzToAnyApBandConversion();
 
     DhcpInfo getDhcpInfo();
@@ -253,5 +255,9 @@
 
     int calculateSignalLevel(int rssi);
 
-    List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<ScanResult> scanResults);
+    List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<android.net.wifi.ScanResult> scanResults);
+
+    boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer);
+
+    void clearWifiConnectedNetworkScorer();
 }
diff --git a/wifi/java/android/net/wifi/ScanResult.aidl b/wifi/java/android/net/wifi/ScanResult.aidl
index bb66722..b30689c 100644
--- a/wifi/java/android/net/wifi/ScanResult.aidl
+++ b/wifi/java/android/net/wifi/ScanResult.aidl
@@ -16,4 +16,4 @@
 
 package android.net.wifi;
 
-parcelable ScanResult;
+@JavaOnlyStableParcelable parcelable ScanResult;
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 3413305..3fda6cd 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -17,6 +17,7 @@
 package android.net.wifi;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -27,8 +28,10 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
@@ -576,67 +579,120 @@
     @UnsupportedAppUsage
     public List<String> anqpLines;
 
-    /** information elements from beacon
-     * @hide
+    /**
+     * information elements from beacon.
      */
     public static class InformationElement {
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_SSID = 0;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_SUPPORTED_RATES = 1;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_TIM = 5;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_BSS_LOAD = 11;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_ERP = 42;
+        /** @hide */
         public static final int EID_HT_CAPABILITIES = 45;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_RSN = 48;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_HT_OPERATION = 61;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_INTERWORKING = 107;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_ROAMING_CONSORTIUM = 111;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_EXTENDED_CAPS = 127;
+        /** @hide */
         public static final int EID_VHT_CAPABILITIES = 191;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_VHT_OPERATION = 192;
+        /** @hide */
         @UnsupportedAppUsage
         public static final int EID_VSA = 221;
+        /** @hide */
         public static final int EID_EXTENSION_PRESENT = 255;
 
-        /**
-         * Extension IDs
-         */
+        // Extension IDs
+        /** @hide */
         public static final int EID_EXT_HE_CAPABILITIES = 35;
+        /** @hide */
         public static final int EID_EXT_HE_OPERATION = 36;
 
+        /** @hide */
         @UnsupportedAppUsage
         public int id;
+        /** @hide */
         public int idExt;
+
+        /** @hide */
         @UnsupportedAppUsage
         public byte[] bytes;
 
+        /** @hide */
         public InformationElement() {
         }
 
-        public InformationElement(InformationElement rhs) {
+        public InformationElement(@NonNull InformationElement rhs) {
             this.id = rhs.id;
             this.idExt = rhs.idExt;
             this.bytes = rhs.bytes.clone();
         }
+
+        /**
+         * The element ID of the information element. Defined in the IEEE 802.11-2016 spec
+         * Table 9-77.
+         */
+        public int getId() {
+            return id;
+        }
+
+        /**
+         * The element ID Extension of the information element. Defined in the IEEE 802.11-2016 spec
+         * Table 9-77.
+         */
+        public int getIdExt() {
+            return idExt;
+        }
+
+        /**
+         * Get the specific content of the information element.
+         */
+        @NonNull
+        public ByteBuffer getBytes() {
+            return ByteBuffer.wrap(bytes).asReadOnlyBuffer();
+        }
     }
 
-    /** information elements found in the beacon
+    /**
+     * information elements found in the beacon.
      * @hide
      */
     @UnsupportedAppUsage
     public InformationElement[] informationElements;
+    /**
+     * Get all information elements found in the beacon.
+     */
+    @NonNull
+    public List<InformationElement> getInformationElements() {
+        return Collections.unmodifiableList(Arrays.asList(informationElements));
+    }
 
     /** ANQP response elements.
      * @hide
@@ -762,8 +818,8 @@
         this.wifiSsid = wifiSsid;
     }
 
-    /** copy constructor {@hide} */
-    public ScanResult(ScanResult source) {
+    /** copy constructor */
+    public ScanResult(@NonNull ScanResult source) {
         if (source != null) {
             wifiSsid = source.wifiSsid;
             SSID = source.SSID;
@@ -929,9 +985,8 @@
         }
     }
 
-    /** Implement the Parcelable interface {@hide} */
-    @UnsupportedAppUsage
-    public static final @android.annotation.NonNull Creator<ScanResult> CREATOR =
+    /** Implement the Parcelable interface */
+    public static final @NonNull Creator<ScanResult> CREATOR =
         new Creator<ScanResult>() {
             public ScanResult createFromParcel(Parcel in) {
                 WifiSsid wifiSsid = null;
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index a77d30a..c02f8c3 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -24,6 +24,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
@@ -36,7 +37,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
-import java.util.concurrent.Executor;
 
 /**
  * Configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot).
@@ -45,22 +45,23 @@
  * framework how it should configure a hotspot.
  *
  * System apps can use this to configure a tethered hotspot using
- * {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} and
- * {@link WifiManager#setSoftApConfiguration(SoftApConfiguration)}
+ * {@code WifiManager#startTetheredHotspot(SoftApConfiguration)} and
+ * {@code WifiManager#setSoftApConfiguration(SoftApConfiguration)}
  * or local-only hotspot using
- * {@link WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
+ * {@code WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
  * WifiManager.LocalOnlyHotspotCallback)}.
  *
  * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to
  * create a new instance.
  *
- * @hide
  */
-@SystemApi
 public final class SoftApConfiguration implements Parcelable {
 
+    private static final String TAG = "SoftApConfiguration";
+
     @VisibleForTesting
     static final int PSK_MIN_LEN = 8;
+
     @VisibleForTesting
     static final int PSK_MAX_LEN = 63;
 
@@ -207,22 +208,24 @@
     private final int mShutdownTimeoutMillis;
 
     /**
-     * Security types we support.
+     * THe definition of security type OPEN.
      */
-    /** @hide */
-    @SystemApi
     public static final int SECURITY_TYPE_OPEN = 0;
 
-    /** @hide */
-    @SystemApi
+
+    /**
+     * The definition of security type WPA2-PSK.
+     */
     public static final int SECURITY_TYPE_WPA2_PSK = 1;
 
-    /** @hide */
-    @SystemApi
+    /**
+     * The definition of security type WPA3-SAE Transition mode.
+     */
     public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2;
 
-    /** @hide */
-    @SystemApi
+    /**
+     * The definition of security type WPA3-SAE.
+     */
     public static final int SECURITY_TYPE_WPA3_SAE = 3;
 
     /** @hide */
@@ -346,7 +349,7 @@
 
     /**
      * Return String set to be the SSID for the AP.
-     * {@link #setSsid(String)}.
+     * {@link Builder#setSsid(String)}.
      */
     @Nullable
     public String getSsid() {
@@ -364,7 +367,7 @@
 
     /**
      * Returns String set to be passphrase for current AP.
-     * {@link #setPassphrase(String, @SecurityType int)}.
+     * {@link Builder#setPassphrase(String, int)}.
      */
     @Nullable
     public String getPassphrase() {
@@ -383,7 +386,10 @@
     /**
      * Returns {@link BandType} set to be the band for the AP.
      * {@link Builder#setBand(@BandType int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public @BandType int getBand() {
         return mBand;
     }
@@ -391,7 +397,10 @@
     /**
      * Returns Integer set to be the channel for the AP.
      * {@link Builder#setChannel(int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public int getChannel() {
         return mChannel;
     }
@@ -408,7 +417,10 @@
     /**
      * Returns the maximum number of clients that can associate to the AP.
      * {@link Builder#setMaxNumberOfClients(int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public int getMaxNumberOfClients() {
         return mMaxNumberOfClients;
     }
@@ -417,7 +429,10 @@
      * Returns the shutdown timeout in milliseconds.
      * The Soft AP will shutdown when there are no devices associated to it for
      * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public int getShutdownTimeoutMillis() {
         return mShutdownTimeoutMillis;
     }
@@ -426,7 +441,10 @@
      * Returns a flag indicating whether clients need to be pre-approved by the user.
      * (true: authorization required) or not (false: not required).
      * {@link Builder#enableClientControlByUser(Boolean)}.
+     *
+     * @hide
      */
+    @SystemApi
     public boolean isClientControlByUserEnabled() {
         return mClientControlByUser;
     }
@@ -435,8 +453,11 @@
      * Returns List of clients which aren't allowed to associate to the AP.
      *
      * Clients are configured using {@link Builder#setClientList(List, List)}
+     *
+     * @hide
      */
     @NonNull
+    @SystemApi
     public List<MacAddress> getBlockedClientList() {
         return mBlockedClientList;
     }
@@ -444,19 +465,77 @@
     /**
      * List of clients which are allowed to associate to the AP.
      * Clients are configured using {@link Builder#setClientList(List, List)}
+     *
+     * @hide
      */
     @NonNull
+    @SystemApi
     public List<MacAddress> getAllowedClientList() {
         return mAllowedClientList;
     }
 
     /**
+     * Returns a {@link WifiConfiguration} representation of this {@link SoftApConfiguration}.
+     * Note that SoftApConfiguration may contain configuration which is cannot be represented
+     * by the legacy WifiConfiguration, in such cases a null will be returned.
+     *
+     * <li> SoftAp band in {@link WifiConfiguration.apBand} only supports
+     * 2GHz, 5GHz, 2GHz+5GHz bands, so conversion is limited to these bands. </li>
+     *
+     * <li> SoftAp security type in {@link WifiConfiguration.KeyMgmt} only supports
+     * NONE, WPA2_PSK, so conversion is limited to these security type.</li>
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public WifiConfiguration toWifiConfiguration() {
+        WifiConfiguration wifiConfig = new WifiConfiguration();
+        wifiConfig.SSID = mSsid;
+        if (mBssid != null) {
+            wifiConfig.BSSID = mBssid.toString();
+        }
+        wifiConfig.preSharedKey = mPassphrase;
+        wifiConfig.hiddenSSID = mHiddenSsid;
+        wifiConfig.apChannel = mChannel;
+        switch (mSecurityType) {
+            case SECURITY_TYPE_OPEN:
+                wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+                break;
+            case SECURITY_TYPE_WPA2_PSK:
+                wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
+                break;
+            default:
+                Log.e(TAG, "Convert fail, unsupported security type :" + mSecurityType);
+                return null;
+        }
+
+        switch (mBand) {
+            case BAND_2GHZ:
+                wifiConfig.apBand  = WifiConfiguration.AP_BAND_2GHZ;
+                break;
+            case BAND_5GHZ:
+                wifiConfig.apBand  = WifiConfiguration.AP_BAND_5GHZ;
+                break;
+            case BAND_ANY:
+                wifiConfig.apBand  = WifiConfiguration.AP_BAND_ANY;
+                break;
+            default:
+                Log.e(TAG, "Convert fail, unsupported band setting :" + mBand);
+                return null;
+        }
+        return wifiConfig;
+    }
+
+    /**
      * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a
      * Soft AP.
      *
      * All fields are optional. By default, SSID and BSSID are automatically chosen by the
      * framework, and an open network is created.
+     *
+     * @hide
      */
+    @SystemApi
     public static final class Builder {
         private String mSsid;
         private MacAddress mBssid;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index b2fbb40..e84369f 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -938,8 +938,10 @@
     }
 
     /**
-     * Indicate whther the network is trusted or not. Networks are considered trusted
+     * Indicate whether the network is trusted or not. Networks are considered trusted
      * if the user explicitly allowed this network connection.
+     * This bit can be used by suggestion network, see
+     * {@link WifiNetworkSuggestion.Builder#setUnTrusted(boolean)}
      * @hide
      */
     public boolean trusted;
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 7cd00b9..f2a875b 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -124,11 +124,21 @@
     private int mTxLinkSpeed;
 
     /**
+     * Max supported Tx(transmit) link speed in Mbps
+     */
+    private int mMaxSupportedTxLinkSpeed;
+
+    /**
      * Rx(receive) Link speed in Mbps
      */
     private int mRxLinkSpeed;
 
     /**
+     * Max supported Rx(receive) link speed in Mbps
+     */
+    private int mMaxSupportedRxLinkSpeed;
+
+    /**
      * Frequency in MHz
      */
     public static final String FREQUENCY_UNITS = "MHz";
@@ -303,6 +313,8 @@
         setLinkSpeed(LINK_SPEED_UNKNOWN);
         setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
         setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
+        setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
+        setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
         setFrequency(-1);
         setMeteredHint(false);
         setEphemeral(false);
@@ -356,6 +368,8 @@
             mRxSuccessRate = source.mRxSuccessRate;
             score = source.score;
             mWifiStandard = source.mWifiStandard;
+            mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed;
+            mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed;
         }
     }
 
@@ -552,6 +566,15 @@
     }
 
     /**
+     * Returns the maximum supported transmit link speed in Mbps
+     * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
+     * unknown. @see #LINK_SPEED_UNKNOWN
+     */
+    public int getMaxSupportedTxLinkSpeedMbps() {
+        return mMaxSupportedTxLinkSpeed;
+    }
+
+    /**
      * Update the last transmitted packet bit rate in Mbps.
      * @hide
      */
@@ -560,6 +583,14 @@
     }
 
     /**
+     * Set the maximum supported transmit link speed in Mbps
+     * @hide
+     */
+    public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) {
+        mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed;
+    }
+
+    /**
      * Returns the current receive link speed in Mbps.
      * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
      * @see #LINK_SPEED_UNKNOWN
@@ -570,6 +601,15 @@
     }
 
     /**
+     * Returns the maximum supported receive link speed in Mbps
+     * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
+     * unknown. @see #LINK_SPEED_UNKNOWN
+     */
+    public int getMaxSupportedRxLinkSpeedMbps() {
+        return mMaxSupportedRxLinkSpeed;
+    }
+
+    /**
      * Update the last received packet bit rate in Mbps.
      * @hide
      */
@@ -578,6 +618,14 @@
     }
 
     /**
+     * Set the maximum supported receive link speed in Mbps
+     * @hide
+     */
+    public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) {
+        mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed;
+    }
+
+    /**
      * Returns the current frequency in {@link #FREQUENCY_UNITS}.
      * @return the frequency.
      * @see #FREQUENCY_UNITS
@@ -864,7 +912,11 @@
                 .append(", RSSI: ").append(mRssi)
                 .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
                 .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
+                .append(", Max Supported Tx Link speed: ")
+                .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS)
                 .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS)
+                .append(", Max Supported Rx Link speed: ")
+                .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS)
                 .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS)
                 .append(", Net ID: ").append(mNetworkId)
                 .append(", Metered hint: ").append(mMeteredHint)
@@ -917,6 +969,8 @@
         dest.writeString(mFqdn);
         dest.writeString(mProviderFriendlyName);
         dest.writeInt(mWifiStandard);
+        dest.writeInt(mMaxSupportedTxLinkSpeed);
+        dest.writeInt(mMaxSupportedRxLinkSpeed);
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -959,6 +1013,8 @@
                 info.mFqdn = in.readString();
                 info.mProviderFriendlyName = in.readString();
                 info.mWifiStandard = in.readInt();
+                info.mMaxSupportedTxLinkSpeed = in.readInt();
+                info.mMaxSupportedRxLinkSpeed = in.readInt();
                 return info;
             }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ec3de43..c35303d 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -193,6 +193,14 @@
      */
     public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5;
 
+    /**
+     * Reason code if one or more of the network suggestions added is not allowed.
+     *
+     * This error may be caused by suggestion is using SIM-based encryption method, but calling app
+     * is not carrier privileged.
+     */
+    public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6;
+
     /** @hide */
     @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = {
             STATUS_NETWORK_SUGGESTIONS_SUCCESS,
@@ -201,6 +209,7 @@
             STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
             STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP,
             STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
+            STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface NetworkSuggestionsStatusCode {}
@@ -1948,6 +1957,15 @@
      * @param config The Passpoint configuration to be added
      * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on
      *                                  the device.
+     *
+     * Deprecated for general app usage - except DO/PO apps.
+     * See {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} to
+     * create a passpoint suggestion.
+     * See {@link #addNetworkSuggestions(List)}, {@link #removeNetworkSuggestions(List)} for new
+     * API to add Wi-Fi networks for consideration when auto-connecting to wifi.
+     * <b>Compatibility Note:</b> For applications targeting
+     * {@link android.os.Build.VERSION_CODES#R} or above, except for system of DO/PO apps, this API
+     * will throw {@link IllegalArgumentException}
      */
     public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
         try {
@@ -2482,6 +2500,20 @@
     }
 
     /**
+     * Check if the chipset supports a certain Wi-Fi standard.
+     * @param standard the IEEE 802.11 standard to check on.
+     *        valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
+     * @return {@code true} if supported, {@code false} otherwise.
+     */
+    public boolean isWifiStandardSupported(@ScanResult.WifiStandard int standard) {
+        try {
+            return mService.isWifiStandardSupported(standard);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and
      * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}.
      *
@@ -2971,7 +3003,7 @@
      * Each application can make a single active call to this method. The {@link
      * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
      * requestor with a {@link LocalOnlyHotspotReservation} that contains a
-     * {@link WifiConfiguration} with the SSID, security type and credentials needed to connect
+     * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect
      * to the hotspot.  Communicating this information is up to the application.
      * <p>
      * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
@@ -3136,7 +3168,7 @@
      * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes.  Callers will
      * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
      * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
-     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(WifiConfiguration)} and
+     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and
      * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
      * <p>
      * Applications should have the
@@ -3223,9 +3255,13 @@
      * Gets the Wi-Fi AP Configuration.
      * @return AP details in WifiConfiguration
      *
+     * Note that AP detail may contain configuration which is cannot be represented
+     * by the legacy WifiConfiguration, in such cases a null will be returned.
+     *
      * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead.
      * @hide
      */
+    @Nullable
     @SystemApi
     @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE)
     @Deprecated
@@ -3711,13 +3747,13 @@
     }
 
     /**
-     * LocalOnlyHotspotReservation that contains the {@link WifiConfiguration} for the active
+     * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active
      * LocalOnlyHotspot request.
      * <p>
      * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
      * LocalOnlyHotspotReservation in the
      * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call.  This
-     * reservation contains the relevant {@link WifiConfiguration}.
+     * reservation contains the relevant {@link SoftApConfiguration}.
      * When an application is done with the LocalOnlyHotspot, they should call {@link
      * LocalOnlyHotspotReservation#close()}.  Once this happens, the application will not receive
      * any further callbacks. If the LocalOnlyHotspot is stopped due to a
@@ -3727,18 +3763,38 @@
     public class LocalOnlyHotspotReservation implements AutoCloseable {
 
         private final CloseGuard mCloseGuard = new CloseGuard();
-        private final WifiConfiguration mConfig;
+        private final SoftApConfiguration mSoftApConfig;
+        private final WifiConfiguration mWifiConfig;
         private boolean mClosed = false;
 
         /** @hide */
         @VisibleForTesting
-        public LocalOnlyHotspotReservation(WifiConfiguration config) {
-            mConfig = config;
+        public LocalOnlyHotspotReservation(SoftApConfiguration config) {
+            mSoftApConfig = config;
+            mWifiConfig = config.toWifiConfiguration();
             mCloseGuard.open("close");
         }
 
+        /**
+         * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS).
+         * May be null if hotspot enabled and security type is not
+         * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}.
+         *
+         * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the
+         * LOHS configuration.
+         */
+        @Deprecated
+        @Nullable
         public WifiConfiguration getWifiConfiguration() {
-            return mConfig;
+            return mWifiConfig;
+        }
+
+        /**
+         * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS).
+         */
+        @NonNull
+        public SoftApConfiguration getSoftApConfiguration() {
+            return mSoftApConfig;
         }
 
         @Override
@@ -3835,7 +3891,7 @@
         }
 
         @Override
-        public void onHotspotStarted(WifiConfiguration config) {
+        public void onHotspotStarted(SoftApConfiguration config) {
             WifiManager manager = mWifiManager.get();
             if (manager == null) return;
 
@@ -3927,7 +3983,7 @@
         /**
          * LocalOnlyHotspot started with the supplied config.
          */
-        public void onStarted(WifiConfiguration config) {};
+        public void onStarted(SoftApConfiguration config) {};
 
         /**
          * LocalOnlyHotspot stopped.
@@ -3967,7 +4023,7 @@
         }
 
         @Override
-        public void onHotspotStarted(WifiConfiguration config) {
+        public void onHotspotStarted(SoftApConfiguration config) {
             WifiManager manager = mWifiManager.get();
             if (manager == null) return;
 
@@ -5806,4 +5862,186 @@
             return new SparseArray<>();
         }
     }
+
+    /**
+     * Callback interface for framework to receive network status changes and trigger of updating
+     * {@link WifiUsabilityStatsEntry}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface ScoreChangeCallback {
+        /**
+         * Called by applications to indicate network status.
+         *
+         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
+         *                  {@link WifiConnectedNetworkScorer#start(int)}.
+         * @param isUsable The bit to indicate whether current Wi-Fi network is usable or not.
+         *                 Populated by connected network scorer in applications.
+         */
+        void onStatusChange(int sessionId, boolean isUsable);
+
+        /**
+         * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}.
+         * To receive update applications need to add WifiUsabilityStatsEntry listener. See
+         * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}.
+         *
+         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
+         *                  {@link WifiConnectedNetworkScorer#start(int)}.
+         */
+        void onTriggerUpdateOfWifiUsabilityStats(int sessionId);
+    }
+
+    /**
+     * Callback proxy for {@link ScoreChangeCallback} objects.
+     *
+     * @hide
+     */
+    private class ScoreChangeCallbackProxy implements ScoreChangeCallback {
+        private final IScoreChangeCallback mScoreChangeCallback;
+
+        private ScoreChangeCallbackProxy(IScoreChangeCallback callback) {
+            mScoreChangeCallback = callback;
+        }
+
+        @Override
+        public void onStatusChange(int sessionId, boolean isUsable) {
+            try {
+                mScoreChangeCallback.onStatusChange(sessionId, isUsable);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        @Override
+        public void onTriggerUpdateOfWifiUsabilityStats(int sessionId) {
+            try {
+                mScoreChangeCallback.onTriggerUpdateOfWifiUsabilityStats(sessionId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set
+     * when calling
+     * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface WifiConnectedNetworkScorer {
+        /**
+         * Called by framework to indicate the start of a network connection.
+         * @param sessionId The ID to indicate current Wi-Fi network connection.
+         */
+        void start(int sessionId);
+
+        /**
+         * Called by framework to indicate the end of a network connection.
+         * @param sessionId The ID to indicate current Wi-Fi network connection obtained from
+         *                  {@link WifiConnectedNetworkScorer#start(int)}.
+         */
+        void stop(int sessionId);
+
+        /**
+         * Framework sets callback for score change events after application sets its scorer.
+         * @param cbImpl The instance for {@link WifiManager#ScoreChangeCallback}. Should be
+         * implemented and instantiated by framework.
+         */
+        void setScoreChangeCallback(@NonNull ScoreChangeCallback cbImpl);
+    }
+
+    /**
+     * Callback proxy for {@link WifiConnectedNetworkScorer} objects.
+     *
+     * @hide
+     */
+    private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub {
+        private Executor mExecutor;
+        private WifiConnectedNetworkScorer mScorer;
+
+        WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) {
+            mExecutor = executor;
+            mScorer = scorer;
+        }
+
+        @Override
+        public void start(int sessionId) {
+            if (mVerboseLoggingEnabled) {
+                Log.v(TAG, "WifiConnectedNetworkScorer: " + "start: sessionId=" + sessionId);
+            }
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mScorer.start(sessionId));
+        }
+
+        @Override
+        public void stop(int sessionId) {
+            if (mVerboseLoggingEnabled) {
+                Log.v(TAG, "WifiConnectedNetworkScorer: " + "stop: sessionId=" + sessionId);
+            }
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mScorer.stop(sessionId));
+        }
+
+        @Override
+        public void setScoreChangeCallback(IScoreChangeCallback cbImpl) {
+            if (mVerboseLoggingEnabled) {
+                Log.v(TAG, "WifiConnectedNetworkScorer: "
+                        + "setScoreChangeCallback: cbImpl=" + cbImpl);
+            }
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mScorer.setScoreChangeCallback(
+                    new ScoreChangeCallbackProxy(cbImpl)));
+        }
+    }
+
+    /**
+     * Set a callback for Wi-Fi connected network scorer.  See {@link WifiConnectedNetworkScorer}.
+     * Only a single scorer can be set. Caller will be invoked periodically by framework to inform
+     * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer
+     * using {@link clearWifiConnectedNetworkScorer()}.
+     *
+     * @param executor The executor on which callback will be invoked.
+     * @param scorer Scorer for Wi-Fi network implemented by application.
+     * @return true Scorer is set successfully.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
+    public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor,
+            @NonNull WifiConnectedNetworkScorer scorer) {
+        if (executor == null) throw new IllegalArgumentException("executor cannot be null");
+        if (scorer == null) throw new IllegalArgumentException("scorer cannot be null");
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer);
+        }
+        try {
+            return mService.setWifiConnectedNetworkScorer(new Binder(),
+                    new WifiConnectedNetworkScorerProxy(executor, scorer));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Allow caller to clear a previously set scorer. After calling this method,
+     * client will no longer receive information about start and stop of Wi-Fi connection.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE)
+    public void clearWifiConnectedNetworkScorer() {
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "clearWifiConnectedNetworkScorer");
+        }
+        try {
+            mService.clearWifiConnectedNetworkScorer();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index 07afd7f..444e1ef 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -20,7 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityThread;
+import android.app.Application;
 import android.net.MacAddress;
 import android.net.MatchAllNetworkSpecifier;
 import android.net.NetworkRequest;
@@ -30,8 +30,11 @@
 import android.os.PatternMatcher;
 import android.os.Process;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Pair;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
@@ -41,6 +44,7 @@
  * {@link WifiNetworkSpecifier.Builder} class to create an instance.
  */
 public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+    private static final String TAG = "WifiNetworkSpecifier";
 
     /**
      * Builder used to create {@link WifiNetworkSpecifier} objects.
@@ -436,7 +440,22 @@
                     mBssidPatternMatcher,
                     buildWifiConfiguration(),
                     Process.myUid(),
-                    ActivityThread.currentApplication().getApplicationContext().getOpPackageName());
+                    getCurrentApplicationReflectively().getApplicationContext().getOpPackageName());
+        }
+
+        // TODO(b/144102365): Remove once refactor is complete
+        private static Application getCurrentApplicationReflectively() {
+            try {
+                // reflection for static method android.app.ActivityThread#currentApplication()
+                Class<?> klass = Class.forName("android.app.ActivityThread");
+                Method currentApplicationMethod = klass.getDeclaredMethod("currentApplication");
+                Object result = currentApplicationMethod.invoke(null);
+                return (Application) result;
+            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
+                    | InvocationTargetException e) {
+                Log.e(TAG, "Failed to call ActivityThread#currentApplication() reflectively!", e);
+                throw new RuntimeException(e);
+            }
         }
     }
 
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 2fba5a3..6085eae 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -139,6 +139,11 @@
          */
         private @Nullable WifiEnterpriseConfig mWapiEnterpriseConfig;
 
+        /**
+         * Whether this network will be brought up as untrusted (TRUSTED capability bit removed).
+         */
+        private boolean mIsNetworkUntrusted;
+
         public Builder() {
             mSsid = null;
             mBssid =  null;
@@ -159,6 +164,7 @@
             mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
             mWapiPskPassphrase = null;
             mWapiEnterpriseConfig = null;
+            mIsNetworkUntrusted = false;
         }
 
         /**
@@ -468,6 +474,27 @@
             return this;
         }
 
+        /**
+         * Specifies whether the system will bring up the network (if selected) as untrusted. An
+         * untrusted network has its {@link android.net.NetworkCapabilities#NET_CAPABILITY_TRUSTED}
+         * capability removed. The Wi-Fi network selection process may use this information to
+         * influence priority of the suggested network for Wi-Fi network selection (most likely to
+         * reduce it). The connectivity service may use this information to influence the overall
+         * network configuration of the device.
+         * <p>
+         * <li> An untrusted network's credentials may not be shared with the user using
+         * {@link #setCredentialSharedWithUser(boolean)}.</li>
+         * <li> If not set, defaults to false (i.e. network is trusted).</li>
+         *
+         * @param isUntrusted Boolean indicating whether the network should be brought up untrusted
+         *                    (if true) or trusted (if false).
+         * @return Instance of {@link Builder} to enable chaining of the builder method.
+         */
+        public @NonNull Builder setUntrusted(boolean isUntrusted) {
+            mIsNetworkUntrusted = isUntrusted;
+            return this;
+        }
+
         private void setSecurityParamsInWifiConfiguration(
                 @NonNull WifiConfiguration configuration) {
             if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
@@ -546,6 +573,7 @@
             wifiConfiguration.meteredOverride =
                     mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED
                             : WifiConfiguration.METERED_OVERRIDE_NONE;
+            wifiConfiguration.trusted = !mIsNetworkUntrusted;
             mPasspointConfiguration.setCarrierId(mCarrierId);
             return wifiConfiguration;
         }
@@ -635,21 +663,28 @@
                     }
                     mIsSharedWithUser = false;
                 }
-
-                if (!mIsSharedWithUser && !mIsInitialAutoJoinEnabled) {
-                    throw new IllegalStateException("Should have not a network with both "
-                            + "setIsUserAllowedToManuallyConnect and "
-                            + "setIsAutoJoinEnabled set to false");
-                }
             }
-
+            if (!mIsSharedWithUser && !mIsInitialAutoJoinEnabled) {
+                throw new IllegalStateException("Should have not a network with both "
+                        + "setCredentialSharedWithUser and "
+                        + "setIsAutoJoinEnabled set to false");
+            }
+            if (mIsNetworkUntrusted) {
+                if (mIsSharedWithUserSet && mIsSharedWithUser) {
+                    throw new IllegalStateException("Should not be both"
+                            + "setCredentialSharedWithUser and +"
+                            + "setIsNetworkAsUntrusted to true");
+                }
+                mIsSharedWithUser = false;
+            }
             return new WifiNetworkSuggestion(
                     wifiConfiguration,
                     mPasspointConfiguration,
                     mIsAppInteractionRequired,
                     mIsUserInteractionRequired,
                     mIsSharedWithUser,
-                    mIsInitialAutoJoinEnabled);
+                    mIsInitialAutoJoinEnabled,
+                    mIsNetworkUntrusted);
         }
     }
 
@@ -657,12 +692,14 @@
      * Network configuration for the provided network.
      * @hide
      */
+    @NonNull
     public final WifiConfiguration wifiConfiguration;
 
     /**
      * Passpoint configuration for the provided network.
      * @hide
      */
+    @Nullable
     public final PasspointConfiguration passpointConfiguration;
 
     /**
@@ -690,14 +727,22 @@
      */
     public final boolean isInitialAutoJoinEnabled;
 
+    /**
+     * Whether this network will be brought up as untrusted (TRUSTED capability bit removed).
+     * @hide
+     */
+    public final boolean isNetworkUntrusted;
+
+
     /** @hide */
     public WifiNetworkSuggestion() {
-        this.wifiConfiguration = null;
+        this.wifiConfiguration = new WifiConfiguration();
         this.passpointConfiguration = null;
         this.isAppInteractionRequired = false;
         this.isUserInteractionRequired = false;
         this.isUserAllowedToManuallyConnect = true;
         this.isInitialAutoJoinEnabled = true;
+        this.isNetworkUntrusted = false;
     }
 
     /** @hide */
@@ -706,7 +751,8 @@
                                  boolean isAppInteractionRequired,
                                  boolean isUserInteractionRequired,
                                  boolean isUserAllowedToManuallyConnect,
-                                 boolean isInitialAutoJoinEnabled) {
+                                 boolean isInitialAutoJoinEnabled,
+            boolean isNetworkUntrusted) {
         checkNotNull(networkConfiguration);
         this.wifiConfiguration = networkConfiguration;
         this.passpointConfiguration = passpointConfiguration;
@@ -715,6 +761,7 @@
         this.isUserInteractionRequired = isUserInteractionRequired;
         this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect;
         this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled;
+        this.isNetworkUntrusted = isNetworkUntrusted;
     }
 
     public static final @NonNull Creator<WifiNetworkSuggestion> CREATOR =
@@ -727,7 +774,8 @@
                             in.readBoolean(), // isAppInteractionRequired
                             in.readBoolean(), // isUserInteractionRequired
                             in.readBoolean(), // isSharedCredentialWithUser
-                            in.readBoolean()  // isAutoJoinEnabled
+                            in.readBoolean(),  // isAutoJoinEnabled
+                            in.readBoolean()
                     );
                 }
 
@@ -750,6 +798,7 @@
         dest.writeBoolean(isUserInteractionRequired);
         dest.writeBoolean(isUserAllowedToManuallyConnect);
         dest.writeBoolean(isInitialAutoJoinEnabled);
+        dest.writeBoolean(isNetworkUntrusted);
     }
 
     @Override
@@ -789,9 +838,31 @@
                 .append(", FQDN=").append(wifiConfiguration.FQDN)
                 .append(", isAppInteractionRequired=").append(isAppInteractionRequired)
                 .append(", isUserInteractionRequired=").append(isUserInteractionRequired)
-                .append(", isUserAllowedToManuallyConnect=").append(isUserAllowedToManuallyConnect)
+                .append(", isCredentialSharedWithUser=").append(isUserAllowedToManuallyConnect)
                 .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled)
+                .append(", isUnTrusted=").append(isNetworkUntrusted)
                 .append(" ]");
         return sb.toString();
     }
+
+    /**
+     * Get the {@link WifiConfiguration} associated with this Suggestion.
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public WifiConfiguration getWifiConfiguration() {
+        return wifiConfiguration;
+    }
+
+    /**
+     * Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this
+     * Suggestion is not for a Passpoint network.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public PasspointConfiguration getPasspointConfiguration() {
+        return passpointConfiguration;
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 4f602fa..18533ef 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -291,28 +291,46 @@
         @NonNull
         @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
         public final List<HiddenNetwork> hiddenNetworks = new ArrayList<>();
-        /** period of background scan; in millisecond, 0 => single shot scan */
+        /**
+         * period of background scan; in millisecond, 0 => single shot scan
+         * @deprecated Background scan support is removed.
+         */
+        @Deprecated
         public int periodInMs;
-        /** must have a valid REPORT_EVENT value */
+        /**
+         * must have a valid REPORT_EVENT value
+         * @deprecated Background scan support is removed.
+         */
+        @Deprecated
         public int reportEvents;
-        /** defines number of bssids to cache from each scan */
+        /**
+         * defines number of bssids to cache from each scan
+         * @deprecated Background scan support is removed.
+         */
+        @Deprecated
         public int numBssidsPerScan;
         /**
          * defines number of scans to cache; use it with REPORT_EVENT_AFTER_BUFFER_FULL
          * to wake up at fixed interval
+         * @deprecated Background scan support is removed.
          */
+        @Deprecated
         public int maxScansToCache;
         /**
          * if maxPeriodInMs is non zero or different than period, then this bucket is
          * a truncated binary exponential backoff bucket and the scan period will grow
          * exponentially as per formula: actual_period(N) = period * (2 ^ (N/stepCount))
          * to maxPeriodInMs
+         * @deprecated Background scan support is removed.
          */
+        @Deprecated
         public int maxPeriodInMs;
         /**
          * for truncated binary exponential back off bucket, number of scans to perform
          * for a given period
+         * @deprecated Background scan support is removed.
          */
+        @Deprecated
         public int stepCount;
         /**
          * Flag to indicate if the scan settings are targeted for PNO scan.
@@ -788,7 +806,9 @@
         /**
          * Framework co-ordinates scans across multiple apps; so it may not give exactly the
          * same period requested. If period of a scan is changed; it is reported by this event.
+         * @deprecated Background scan support is removed.
          */
+        @Deprecated
         public void onPeriodChanged(int periodInMs);
         /**
          * reports results retrieved from background scan and single shot scans
@@ -891,7 +911,9 @@
      * @param listener specifies the object to report events to. This object is also treated as a
      *                 key for this scan, and must also be specified to cancel the scan. Multiple
      *                 scans should also not share this object.
+     * @deprecated Background scan support is removed.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     public void startBackgroundScan(ScanSettings settings, ScanListener listener,
             WorkSource workSource) {
@@ -911,7 +933,9 @@
      * stop an ongoing wifi scan
      * @param listener specifies which scan to cancel; must be same object as passed in {@link
      *  #startBackgroundScan}
+     * @deprecated Background scan support is removed.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     public void stopBackgroundScan(ScanListener listener) {
         Objects.requireNonNull(listener, "listener cannot be null");
@@ -927,7 +951,9 @@
     /**
      * reports currently available scan results on appropriate listeners
      * @return true if all scan results were reported correctly
+     * @deprecated Background scan support is removed.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     public boolean getScanResults() {
         validateChannel();
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index a411502..5484d24 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -61,6 +61,9 @@
      * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE},
      * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or
      * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}.
+     *
+     * The bit definition is listed in 5.1.2 WFD Device Information Subelement in
+     * Wi-Fi Display Technical Specification.
      */
     private static final int DEVICE_TYPE                            = 1 << 1 | 1 << 0;
     private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 1 << 2;
@@ -69,6 +72,8 @@
     private static final int SESSION_AVAILABLE_BIT2                 = 1 << 5;
     private static final int SESSION_AVAILABLE                      =
             SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1;
+    /* The support of Content Protection using the HDCP system 2.0/2.1. */
+    private static final int CONTENT_PROTECTION_SUPPORT             = 1 << 8;
 
     private int mCtrlPort;
 
@@ -146,6 +151,26 @@
         }
     }
 
+    /**
+     * @return true if Content Protection using the HDCP system 2.0/2.1 is supported.
+     */
+    public boolean isContentProtectionSupported() {
+        return (mDeviceInfo & CONTENT_PROTECTION_SUPPORT) != 0;
+    }
+
+    /**
+     * Sets whether Content Protection using the HDCP system 2.0/2.1 is supported.
+     *
+     * @param enabled true to indicate that Content Protection is supported, false otherwise.
+     */
+    public void setContentProtectionSupported(boolean enabled) {
+        if (enabled) {
+            mDeviceInfo |= CONTENT_PROTECTION_SUPPORT;
+        } else {
+            mDeviceInfo &= ~CONTENT_PROTECTION_SUPPORT;
+        }
+    }
+
     /** Returns the TCP port at which the WFD Device listens for RTSP messages. */
     public int getControlPort() {
         return mCtrlPort;
diff --git a/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java
new file mode 100644
index 0000000..13ae3b3
--- /dev/null
+++ b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.wificond;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.wifi.ScanResult;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * DeviceWiphyCapabilities for wificond
+ *
+ * @hide
+ */
+@SystemApi
+public final class DeviceWiphyCapabilities implements Parcelable {
+    private static final String TAG = "DeviceWiphyCapabilities";
+
+    private boolean m80211nSupported;
+    private boolean m80211acSupported;
+    private boolean m80211axSupported;
+    private boolean mChannelWidth160MhzSupported;
+    private boolean mChannelWidth80p80MhzSupported;
+    private int mMaxNumberTxSpatialStreams;
+    private int mMaxNumberRxSpatialStreams;
+
+
+    /** public constructor */
+    public DeviceWiphyCapabilities() {
+        m80211nSupported = false;
+        m80211acSupported = false;
+        m80211axSupported = false;
+        mChannelWidth160MhzSupported = false;
+        mChannelWidth80p80MhzSupported = false;
+        mMaxNumberTxSpatialStreams = 1;
+        mMaxNumberRxSpatialStreams = 1;
+    }
+
+    /**
+     * Get the IEEE 802.11 standard support
+     *
+     * @param standard the IEEE 802.11 standard to check on its support.
+     *        valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
+     * @return {@code true} if supported, {@code false} otherwise.
+     */
+    public boolean isWifiStandardSupported(int standard) {
+        switch (standard) {
+            case ScanResult.WIFI_STANDARD_LEGACY:
+                return true;
+            case ScanResult.WIFI_STANDARD_11N:
+                return m80211nSupported;
+            case ScanResult.WIFI_STANDARD_11AC:
+                return m80211acSupported;
+            case ScanResult.WIFI_STANDARD_11AX:
+                return m80211axSupported;
+            default:
+                Log.e(TAG, "isWifiStandardSupported called with invalid standard: " + standard);
+                return false;
+        }
+    }
+
+    /**
+     * Set the IEEE 802.11 standard support
+     *
+     * @param standard the IEEE 802.11 standard to set its support.
+     *        valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
+     * @param support {@code true} if supported, {@code false} otherwise.
+     */
+    public void setWifiStandardSupport(int standard, boolean support) {
+        switch (standard) {
+            case ScanResult.WIFI_STANDARD_11N:
+                m80211nSupported = support;
+                break;
+            case ScanResult.WIFI_STANDARD_11AC:
+                m80211acSupported = support;
+                break;
+            case ScanResult.WIFI_STANDARD_11AX:
+                m80211axSupported = support;
+                break;
+            default:
+                Log.e(TAG, "setWifiStandardSupport called with invalid standard: " + standard);
+        }
+    }
+
+    /**
+     * Get the support for channel bandwidth
+     *
+     * @param chWidth valid values from {@link ScanResult}'s {@code CHANNEL_WIDTH_}
+     *
+     * @return {@code true} if supported, {@code false} otherwise.
+     */
+    public boolean isChannelWidthSupported(int chWidth) {
+        switch (chWidth) {
+            case ScanResult.CHANNEL_WIDTH_20MHZ:
+                return true;
+            case ScanResult.CHANNEL_WIDTH_40MHZ:
+                return (m80211nSupported || m80211acSupported || m80211axSupported);
+            case ScanResult.CHANNEL_WIDTH_80MHZ:
+                return (m80211acSupported || m80211axSupported);
+            case ScanResult.CHANNEL_WIDTH_160MHZ:
+                return mChannelWidth160MhzSupported;
+            case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+                return mChannelWidth80p80MhzSupported;
+            default:
+                Log.e(TAG, "isChannelWidthSupported called with invalid channel width: " + chWidth);
+        }
+        return false;
+    }
+
+    /**
+     * Set support for channel bandwidth
+     *
+     * @param chWidth valid values are {@link ScanResult#CHANNEL_WIDTH_160MHZ} and
+     *        {@link ScanResult#CHANNEL_WIDTH_80MHZ_PLUS_MHZ}
+     * @param support {@code true} if supported, {@code false} otherwise.
+     */
+    public void setChannelWidthSupported(int chWidth, boolean support) {
+        switch (chWidth) {
+            case ScanResult.CHANNEL_WIDTH_160MHZ:
+                mChannelWidth160MhzSupported = support;
+                break;
+            case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+                mChannelWidth80p80MhzSupported = support;
+                break;
+            default:
+                Log.e(TAG, "setChannelWidthSupported called with Invalid channel width: "
+                        + chWidth);
+        }
+    }
+
+    /**
+     * Get maximum number of transmit spatial streams
+     *
+     * @return number of spatial streams
+     */
+    public int getMaxNumberTxSpatialStreams() {
+        return mMaxNumberTxSpatialStreams;
+    }
+
+    /**
+     * Set maximum number of transmit spatial streams
+     *
+     * @param streams number of spatial streams
+     */
+    public void setMaxNumberTxSpatialStreams(int streams) {
+        mMaxNumberTxSpatialStreams = streams;
+    }
+
+    /**
+     * Get maximum number of receive spatial streams
+     *
+     * @return number of streams
+     */
+    public int getMaxNumberRxSpatialStreams() {
+        return mMaxNumberRxSpatialStreams;
+    }
+
+    /**
+     * Set maximum number of receive spatial streams
+     *
+     * @param streams number of streams
+     */
+    public void setMaxNumberRxSpatialStreams(int streams) {
+        mMaxNumberRxSpatialStreams = streams;
+    }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof DeviceWiphyCapabilities)) {
+            return false;
+        }
+        DeviceWiphyCapabilities capa = (DeviceWiphyCapabilities) rhs;
+
+        return m80211nSupported == capa.m80211nSupported
+                && m80211acSupported == capa.m80211acSupported
+                && m80211axSupported == capa.m80211axSupported
+                && mChannelWidth160MhzSupported == capa.mChannelWidth160MhzSupported
+                && mChannelWidth80p80MhzSupported == capa.mChannelWidth80p80MhzSupported
+                && mMaxNumberTxSpatialStreams == capa.mMaxNumberTxSpatialStreams
+                && mMaxNumberRxSpatialStreams == capa.mMaxNumberRxSpatialStreams;
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported,
+                mChannelWidth160MhzSupported, mChannelWidth80p80MhzSupported,
+                mMaxNumberTxSpatialStreams, mMaxNumberRxSpatialStreams);
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flags| is ignored.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeBoolean(m80211nSupported);
+        out.writeBoolean(m80211acSupported);
+        out.writeBoolean(m80211axSupported);
+        out.writeBoolean(mChannelWidth160MhzSupported);
+        out.writeBoolean(mChannelWidth80p80MhzSupported);
+        out.writeInt(mMaxNumberTxSpatialStreams);
+        out.writeInt(mMaxNumberRxSpatialStreams);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No");
+        sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No");
+        sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No");
+        sb.append("mChannelWidth160MhzSupported: ")
+                .append(mChannelWidth160MhzSupported ? "Yes" : "No");
+        sb.append("mChannelWidth80p80MhzSupported: ")
+                .append(mChannelWidth80p80MhzSupported ? "Yes" : "No");
+        sb.append("mMaxNumberTxSpatialStreams: ").append(mMaxNumberTxSpatialStreams);
+        sb.append("mMaxNumberRxSpatialStreams: ").append(mMaxNumberRxSpatialStreams);
+
+        return sb.toString();
+    }
+
+    /** implement Parcelable interface */
+    public static final @NonNull Parcelable.Creator<DeviceWiphyCapabilities> CREATOR =
+            new Parcelable.Creator<DeviceWiphyCapabilities>() {
+        /**
+         * Caller is responsible for providing a valid parcel.
+         */
+        @Override
+        public DeviceWiphyCapabilities createFromParcel(Parcel in) {
+            DeviceWiphyCapabilities capabilities = new DeviceWiphyCapabilities();
+            capabilities.m80211nSupported = in.readBoolean();
+            capabilities.m80211acSupported = in.readBoolean();
+            capabilities.m80211axSupported = in.readBoolean();
+            capabilities.mChannelWidth160MhzSupported = in.readBoolean();
+            capabilities.mChannelWidth80p80MhzSupported = in.readBoolean();
+            capabilities.mMaxNumberTxSpatialStreams = in.readInt();
+            capabilities.mMaxNumberRxSpatialStreams = in.readInt();
+            return capabilities;
+        }
+
+        @Override
+        public DeviceWiphyCapabilities[] newArray(int size) {
+            return new DeviceWiphyCapabilities[size];
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java
index f70bdac..4847640 100644
--- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java
+++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java
@@ -1052,6 +1052,22 @@
     }
 
     /**
+     * Get the device phy capabilities for a given interface
+     */
+    @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) {
+        if (mWificond == null) {
+            Log.e(TAG, "Can not query for device wiphy capabilities at this time");
+            return null;
+        }
+
+        try {
+            return mWificond.getDeviceWiphyCapabilities(ifaceName);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Register the provided callback handler for SoftAp events. Note that the Soft AP itself is
      * configured using {@link #setupInterfaceForSoftApMode(String)}.
      *
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 1cf3825..56fa6e2 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -32,6 +32,7 @@
 import android.net.wifi.ISuggestionConnectionStatusListener;
 import android.net.wifi.ITrafficStateCallback;
 import android.net.wifi.ITxPacketCountListener;
+import android.net.wifi.IWifiConnectedNetworkScorer;
 import android.net.wifi.IWifiManager;
 import android.net.wifi.ScanResult;
 import android.net.wifi.SoftApConfiguration;
@@ -253,6 +254,11 @@
     }
 
     @Override
+    public boolean isWifiStandardSupported(int standard) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public boolean needs5GHzToAnyApBandConversion() {
         throw new UnsupportedOperationException();
     }
@@ -600,4 +606,15 @@
             List<ScanResult> scanResults) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public boolean setWifiConnectedNetworkScorer(IBinder binder,
+            IWifiConnectedNetworkScorer scorer) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearWifiConnectedNetworkScorer() {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
index 6884a4e..2efdd97 100644
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -18,6 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertNull;
+
 import android.net.MacAddress;
 import android.os.Parcel;
 
@@ -251,7 +253,7 @@
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void testsetClientListExceptionWhenExistMacAddressInBothList() {
+    public void testSetClientListExceptionWhenExistMacAddressInBothList() {
         final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77");
         final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
         ArrayList<MacAddress> testAllowedClientList = new ArrayList<>();
@@ -262,4 +264,40 @@
         SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
         configBuilder.setClientList(testBlockedClientList, testAllowedClientList);
     }
+
+    @Test
+    public void testToWifiConfigurationWithUnsupportedParameter() {
+        SoftApConfiguration sae_config = new SoftApConfiguration.Builder()
+                .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
+                .build();
+
+        assertNull(sae_config.toWifiConfiguration());
+        SoftApConfiguration band_6g_config = new SoftApConfiguration.Builder()
+                .setBand(SoftApConfiguration.BAND_6GHZ)
+                .build();
+
+        assertNull(band_6g_config.toWifiConfiguration());
+        SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder()
+                .setPassphrase("secretsecret",
+                        SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
+                .build();
+
+        assertNull(sae_transition_config.toWifiConfiguration());
+    }
+
+    @Test
+    public void testToWifiConfigurationWithSupportedParameter() {
+        SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
+                .setPassphrase("secretsecret",
+                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+                .setChannel(149, SoftApConfiguration.BAND_5GHZ)
+                .setHiddenSsid(true)
+                .build();
+        WifiConfiguration wifiConfig = softApConfig.toWifiConfiguration();
+        assertThat(wifiConfig.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+        assertThat(wifiConfig.preSharedKey).isEqualTo("secretsecret");
+        assertThat(wifiConfig.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ);
+        assertThat(wifiConfig.apChannel).isEqualTo(149);
+        assertThat(wifiConfig.hiddenSSID).isEqualTo(true);
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java
index f761234..af85ce0 100644
--- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java
@@ -39,6 +39,8 @@
     private static final String TEST_FQDN = "test.com";
     private static final String TEST_PROVIDER_NAME = "test";
     private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC;
+    private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866;
+    private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200;
 
     /**
      *  Verify parcel write/read with WifiInfo.
@@ -56,6 +58,8 @@
         writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
         writeWifiInfo.setAppPackageName(TEST_PACKAGE_NAME);
         writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
+        writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
+        writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
 
         Parcel parcel = Parcel.obtain();
         writeWifiInfo.writeToParcel(parcel, 0);
@@ -75,5 +79,26 @@
         assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
         assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
         assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
+        assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
+                readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
+        assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
+                readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
+    }
+
+    /**
+     *  Verify values after reset()
+     */
+    @Test
+    public void testWifiInfoResetValue() throws Exception {
+        WifiInfo wifiInfo = new WifiInfo();
+        wifiInfo.reset();
+        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
+        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps());
+        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps());
+        assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps());
+        assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi());
+        assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
+        assertEquals(null, wifiInfo.getBSSID());
+        assertEquals(-1, wifiInfo.getNetworkId());
     }
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 983ac82..f369203 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -82,6 +82,7 @@
 import android.net.wifi.WifiManager.SoftApCallback;
 import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
 import android.net.wifi.WifiManager.TrafficStateCallback;
+import android.net.wifi.WifiManager.WifiConnectedNetworkScorer;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
@@ -105,6 +106,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -138,6 +140,7 @@
     @Mock Executor mExecutor;
     @Mock Executor mAnotherExecutor;
     @Mock ActivityManager mActivityManager;
+    @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
 
     private Handler mHandler;
     private TestLooper mLooper;
@@ -146,6 +149,50 @@
     private ScanResultsCallback mScanResultsCallback;
     private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
 
+    /**
+     * Util function to check public field which used for softap  in WifiConfiguration
+     * same as the value in SoftApConfiguration.
+     *
+     */
+    private boolean compareWifiAndSoftApConfiguration(
+            SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) {
+        if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) {
+            return false;
+        }
+        if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) {
+            return false;
+        }
+        if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) {
+            return false;
+        }
+
+        if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) {
+            return false;
+        }
+        switch (softApConfig.getSecurityType()) {
+            case SoftApConfiguration.SECURITY_TYPE_OPEN:
+                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) {
+                    return false;
+                }
+                break;
+            case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
+                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) {
+                    return false;
+                }
+                break;
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    private SoftApConfiguration generatorTestSoftApConfig() {
+        return new SoftApConfiguration.Builder()
+                .setSsid("TestSSID")
+                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+                .build();
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -210,12 +257,12 @@
      */
     @Test
     public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
-        SoftApConfiguration mSoftApConfig = new SoftApConfiguration.Builder().build();
-        when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(true);
-        assertTrue(mWifiManager.startTetheredHotspot(mSoftApConfig));
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
+        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
+        assertTrue(mWifiManager.startTetheredHotspot(softApConfig));
 
-        when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(false);
-        assertFalse(mWifiManager.startTetheredHotspot(mSoftApConfig));
+        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
+        assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
     }
 
     /**
@@ -237,14 +284,18 @@
      */
     @Test
     public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
                 nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
+        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
 
-        assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
+        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
+        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
+        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
+
         callback.mRes.close();
         verify(mWifiService).stopLocalOnlyHotspot();
     }
@@ -255,15 +306,18 @@
     @Test
     public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
             throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
                 nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
+        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
 
         try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
-            assertEquals(mApConfig, res.getWifiConfiguration());
+            assertEquals(softApConfig, res.getSoftApConfiguration());
+            WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
+            assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
         }
 
         verify(mWifiService).stopLocalOnlyHotspot();
@@ -313,6 +367,7 @@
      */
     @Test
     public void testLocalOnlyHotspotCallback() {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         assertFalse(callback.mOnStartedCalled);
         assertFalse(callback.mOnStoppedCalled);
@@ -321,7 +376,7 @@
 
         // test onStarted
         WifiManager.LocalOnlyHotspotReservation res =
-                mWifiManager.new LocalOnlyHotspotReservation(mApConfig);
+                mWifiManager.new LocalOnlyHotspotReservation(softApConfig);
         callback.onStarted(res);
         assertEquals(res, callback.mRes);
         assertTrue(callback.mOnStartedCalled);
@@ -347,7 +402,7 @@
         public boolean mOnRegistered = false;
         public boolean mOnStartedCalled = false;
         public boolean mOnStoppedCalled = false;
-        public WifiConfiguration mConfig = null;
+        public SoftApConfiguration mConfig = null;
         public LocalOnlyHotspotSubscription mSub = null;
         public long mCallingThreadId = -1;
 
@@ -359,7 +414,7 @@
         }
 
         @Override
-        public void onStarted(WifiConfiguration config) {
+        public void onStarted(SoftApConfiguration config) {
             mOnStartedCalled = true;
             mConfig = config;
             mCallingThreadId = Thread.currentThread().getId();
@@ -378,6 +433,7 @@
     @Test
     public void testLocalOnlyHotspotObserver() {
         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         assertFalse(observer.mOnRegistered);
         assertFalse(observer.mOnStartedCalled);
         assertFalse(observer.mOnStoppedCalled);
@@ -393,18 +449,18 @@
         assertEquals(null, observer.mConfig);
         assertEquals(sub, observer.mSub);
 
-        observer.onStarted(mApConfig);
+        observer.onStarted(softApConfig);
         assertTrue(observer.mOnRegistered);
         assertTrue(observer.mOnStartedCalled);
         assertFalse(observer.mOnStoppedCalled);
-        assertEquals(mApConfig, observer.mConfig);
+        assertEquals(softApConfig, observer.mConfig);
         assertEquals(sub, observer.mSub);
 
         observer.onStopped();
         assertTrue(observer.mOnRegistered);
         assertTrue(observer.mOnStartedCalled);
         assertTrue(observer.mOnStoppedCalled);
-        assertEquals(mApConfig, observer.mConfig);
+        assertEquals(softApConfig, observer.mConfig);
         assertEquals(sub, observer.mSub);
     }
 
@@ -486,6 +542,7 @@
      */
     @Test
     public void testOnStartedIsCalledWithReservation() throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         TestLooper callbackLooper = new TestLooper();
         Handler callbackHandler = new Handler(callbackLooper.getLooper());
@@ -499,11 +556,44 @@
         assertFalse(callback.mOnStartedCalled);
         assertEquals(null, callback.mRes);
         // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(mApConfig);
+        internalCallback.getValue().onHotspotStarted(softApConfig);
         mLooper.dispatchAll();
         callbackLooper.dispatchAll();
         assertTrue(callback.mOnStartedCalled);
-        assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
+        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
+        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
+        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
+    }
+
+    /**
+     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
+     * message from WifiServiceImpl when softap enabled with SAE security type.
+     */
+    @Test
+    public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception {
+        SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
+                .setSsid("TestSSID")
+                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
+                .build();
+        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
+        TestLooper callbackLooper = new TestLooper();
+        Handler callbackHandler = new Handler(callbackLooper.getLooper());
+        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
+                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
+        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
+        callbackLooper.dispatchAll();
+        mLooper.dispatchAll();
+        assertFalse(callback.mOnStartedCalled);
+        assertEquals(null, callback.mRes);
+        // now trigger the callback
+        internalCallback.getValue().onHotspotStarted(softApConfig);
+        mLooper.dispatchAll();
+        callbackLooper.dispatchAll();
+        assertTrue(callback.mOnStartedCalled);
+        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
+        assertEquals(null, callback.mRes.getWifiConfiguration());
     }
 
     /**
@@ -1035,6 +1125,7 @@
      */
     @Test
     public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
         TestLooper observerLooper = new TestLooper();
         Handler observerHandler = new Handler(observerLooper.getLooper());
@@ -1046,11 +1137,11 @@
         mLooper.dispatchAll();
         assertFalse(observer.mOnStartedCalled);
         // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(mApConfig);
+        internalCallback.getValue().onHotspotStarted(softApConfig);
         mLooper.dispatchAll();
         observerLooper.dispatchAll();
         assertTrue(observer.mOnStartedCalled);
-        assertEquals(mApConfig, observer.mConfig);
+        assertEquals(softApConfig, observer.mConfig);
     }
 
     /**
@@ -1246,7 +1337,7 @@
      */
     @Test
     public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception {
-        SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
+        SoftApConfiguration apConfig = generatorTestSoftApConfig();
 
         when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
                 .thenReturn(true);
@@ -1258,7 +1349,7 @@
      */
     @Test
     public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception {
-        SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
+        SoftApConfiguration apConfig = generatorTestSoftApConfig();
 
         when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
                 .thenReturn(false);
@@ -1273,7 +1364,7 @@
         doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any());
 
         try {
-            mWifiManager.setSoftApConfiguration(new SoftApConfiguration.Builder().build());
+            mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig());
             fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
         } catch (SecurityException e) { }
     }
@@ -1868,6 +1959,17 @@
     }
 
     /**
+     * Test behavior of {@link WifiManager#isWifiStandardSupported()}
+     */
+    @Test
+    public void testIsWifiStandardSupported() throws Exception {
+        int standard = ScanResult.WIFI_STANDARD_11AX;
+        when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true);
+        assertTrue(mWifiManager.isWifiStandardSupported(standard));
+        verify(mWifiService).isWifiStandardSupported(standard);
+    }
+
+    /**
      * Test behavior of {@link WifiManager#getDhcpInfo()}
      */
     @Test
@@ -2230,4 +2332,63 @@
         assertEquals(testResults, mWifiManager
                 .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
     }
+
+    /**
+     * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl.
+     */
+    @Test
+    public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
+        mExecutor = new SynchronousExecutor();
+        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+                any(IWifiConnectedNetworkScorer.Stub.class));
+    }
+
+    /**
+     * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl.
+     */
+    @Test
+    public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception {
+        mExecutor = new SynchronousExecutor();
+        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+                any(IWifiConnectedNetworkScorer.Stub.class));
+
+        mWifiManager.clearWifiConnectedNetworkScorer();
+        verify(mWifiService).clearWifiConnectedNetworkScorer();
+    }
+
+    /**
+     * Verify that Wi-Fi connected scorer receives score change callback after registeration.
+     */
+    @Test
+    public void verifyScorerReceiveScoreChangeCallbackAfterRegistration() throws Exception {
+        mExecutor = new SynchronousExecutor();
+        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+        ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor =
+                ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
+        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+                scorerCaptor.capture());
+        scorerCaptor.getValue().setScoreChangeCallback(any());
+        mLooper.dispatchAll();
+        verify(mWifiConnectedNetworkScorer).setScoreChangeCallback(any());
+    }
+
+    /**
+     * Verify that Wi-Fi connected scorer receives session ID when start/stop methods are called.
+     */
+    @Test
+    public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception {
+        mExecutor = new SynchronousExecutor();
+        mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer);
+        ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor =
+                ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class);
+        verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class),
+                callbackCaptor.capture());
+        callbackCaptor.getValue().start(0);
+        callbackCaptor.getValue().stop(10);
+        mLooper.dispatchAll();
+        verify(mWifiConnectedNetworkScorer).start(0);
+        verify(mWifiConnectedNetworkScorer).stop(10);
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index cb1b774..15accc3 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -532,7 +532,7 @@
         configuration.BSSID = TEST_BSSID;
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(
-                configuration, null, false, true, true, false);
+                configuration, null, false, true, true, true, false);
 
         Parcel parcelW = Parcel.obtain();
         suggestion.writeToParcel(parcelW, 0);
@@ -603,14 +603,14 @@
         configuration.BSSID = TEST_BSSID;
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
         WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null, true, false, true, true);
+                new WifiNetworkSuggestion(configuration, null, true, false, true, true, false);
 
         WifiConfiguration configuration1 = new WifiConfiguration();
         configuration1.SSID = TEST_SSID;
         configuration1.BSSID = TEST_BSSID;
         configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
         WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, true, true, false);
+                new WifiNetworkSuggestion(configuration1, null, false, true, true, true, false);
 
         assertEquals(suggestion, suggestion1);
         assertEquals(suggestion.hashCode(), suggestion1.hashCode());
@@ -626,13 +626,13 @@
         configuration.SSID = TEST_SSID;
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null, false, false, true, false);
+                new WifiNetworkSuggestion(configuration, null, false, false, true, true, false);
 
         WifiConfiguration configuration1 = new WifiConfiguration();
         configuration1.SSID = TEST_SSID_1;
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, false, true, false);
+                new WifiNetworkSuggestion(configuration1, null, false, false, true, true, false);
 
         assertNotEquals(suggestion, suggestion1);
     }
@@ -648,13 +648,13 @@
         configuration.BSSID = TEST_BSSID;
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null,  false, false, true, true);
+                new WifiNetworkSuggestion(configuration, null,  false, false, true, true, false);
 
         WifiConfiguration configuration1 = new WifiConfiguration();
         configuration1.SSID = TEST_SSID;
         configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
+                new WifiNetworkSuggestion(configuration1, null, false, false, true, true, false);
 
         assertNotEquals(suggestion, suggestion1);
     }
@@ -669,13 +669,13 @@
         configuration.SSID = TEST_SSID;
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         WifiNetworkSuggestion suggestion =
-                new WifiNetworkSuggestion(configuration, null, false, false, true, true);
+                new WifiNetworkSuggestion(configuration, null, false, false, true, true, false);
 
         WifiConfiguration configuration1 = new WifiConfiguration();
         configuration1.SSID = TEST_SSID;
         configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
         WifiNetworkSuggestion suggestion1 =
-                new WifiNetworkSuggestion(configuration1, null, false, false, true, true);
+                new WifiNetworkSuggestion(configuration1, null, false, false, true, true, false);
 
         assertNotEquals(suggestion, suggestion1);
     }
@@ -723,8 +723,8 @@
      * true on a open network suggestion.
      */
     @Test(expected = IllegalStateException.class)
-    public void testSetIsUserAllowedToManuallyConnectToWithOpenNetwork() {
-        new WifiNetworkSuggestion.Builder()
+    public void testSetCredentialSharedWithUserWithOpenNetwork() {
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
                 .setSsid(TEST_SSID)
                 .setCredentialSharedWithUser(true)
                 .build();
@@ -758,4 +758,67 @@
                 .setIsInitialAutoJoinEnabled(false)
                 .build();
     }
+
+    /**
+     * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
+     * correct value to the WifiConfiguration.
+     */
+    @Test
+    public void testSetIsNetworkAsUntrusted() {
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setSsid(TEST_SSID)
+                .setWpa2Passphrase(TEST_PRESHARED_KEY)
+                .setUntrusted(true)
+                .build();
+        assertTrue(suggestion.isNetworkUntrusted);
+        assertFalse(suggestion.isUserAllowedToManuallyConnect);
+    }
+
+    /**
+     * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
+     * correct value to the WifiConfiguration.
+     * Also the {@link WifiNetworkSuggestion#isUserAllowedToManuallyConnect} should be false;
+     */
+    @Test
+    public void testSetIsNetworkAsUntrustedOnPasspointNetwork() {
+        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setPasspointConfig(passpointConfiguration)
+                .setUntrusted(true)
+                .build();
+        assertTrue(suggestion.isNetworkUntrusted);
+        assertFalse(suggestion.isUserAllowedToManuallyConnect);
+    }
+
+    /**
+     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+     * when set {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} to true and
+     * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true
+     * together.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testSetCredentialSharedWithUserWithSetIsNetworkAsUntrusted() {
+        new WifiNetworkSuggestion.Builder()
+                .setSsid(TEST_SSID)
+                .setWpa2Passphrase(TEST_PRESHARED_KEY)
+                .setCredentialSharedWithUser(true)
+                .setUntrusted(true)
+                .build();
+    }
+
+    /**
+     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+     * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)}
+     * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)}
+     * to false on a passpoint suggestion.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUserForPasspoint() {
+        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
+        new WifiNetworkSuggestion.Builder()
+                .setPasspointConfig(passpointConfiguration)
+                .setCredentialSharedWithUser(false)
+                .setIsInitialAutoJoinEnabled(false)
+                .build();
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
index cea73ef..15a0aac 100644
--- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java
@@ -45,6 +45,7 @@
         // initialize device info flags.
         mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE);
         mSourceInfo.setSessionAvailable(true);
+        mSourceInfo.setContentProtectionSupported(true);
     }
 
     /**
@@ -63,13 +64,16 @@
         info.setSessionAvailable(true);
         assertTrue(info.isSessionAvailable());
 
+        info.setContentProtectionSupported(true);
+        assertTrue(info.isContentProtectionSupported());
+
         info.setControlPort(TEST_CTRL_PORT);
         assertEquals(TEST_CTRL_PORT, info.getControlPort());
 
         info.setMaxThroughput(TEST_MAX_TPUT);
         assertEquals(TEST_MAX_TPUT, info.getMaxThroughput());
 
-        assertEquals("0010270f0400", info.getDeviceInfoHex());
+        assertEquals("0110270f0400", info.getDeviceInfoHex());
     }
 
     /**
diff --git a/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java
new file mode 100644
index 0000000..8e3627a
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.wificond;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.wifi.ScanResult;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.wificond.DeviceWiphyCapabilities}.
+ */
+@SmallTest
+public class DeviceWiphyCapabilitiesTest {
+    @Before
+    public void setUp() {}
+
+    /**
+     *  DeviceWiphyCapabilities object can be serialized and deserialized, while keeping the
+     *  values unchanged.
+     */
+    @Test
+    public void canSerializeAndDeserialize() {
+        DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+        capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true);
+        capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false);
+        capa.setMaxNumberTxSpatialStreams(2);
+        capa.setMaxNumberRxSpatialStreams(1);
+
+        Parcel parcel = Parcel.obtain();
+        capa.writeToParcel(parcel, 0);
+        // Rewind the pointer to the head of the parcel.
+        parcel.setDataPosition(0);
+        DeviceWiphyCapabilities capaDeserialized =
+                DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel);
+
+        assertEquals(capa, capaDeserialized);
+        assertEquals(capa.hashCode(), capaDeserialized.hashCode());
+    }
+
+    /**
+     * Test mapping wifi standard support into channel width support
+     */
+    @Test
+    public void testMappingWifiStandardIntoChannelWidthSupport() {
+        DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false);
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+        assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ));
+        assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ));
+        assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ));
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+        assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ));
+        assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ));
+        assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ));
+
+        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+        assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ));
+        assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ));
+        assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ));
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java
index f3867c1..f262268 100644
--- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java
@@ -38,6 +38,7 @@
 import android.app.AlarmManager;
 import android.app.test.TestAlarmManager;
 import android.content.Context;
+import android.net.wifi.ScanResult;
 import android.net.wifi.SoftApInfo;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiScanner;
@@ -397,7 +398,6 @@
         verify(mWifiScannerImpl).unsubscribeScanEvents();
     }
 
-
     /**
      * Verifies that tearDownInterfaces() returns false when wificond is not started.
      */
@@ -1036,6 +1036,29 @@
         verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT);
     }
 
+    /**
+     * Tests getDeviceWiphyCapabililties
+     */
+    @Test
+    public void testGetDeviceWiphyCapabilities() throws Exception {
+        DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities();
+
+        capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+        capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+        capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+        capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true);
+        capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false);
+        capaExpected.setMaxNumberTxSpatialStreams(2);
+        capaExpected.setMaxNumberRxSpatialStreams(1);
+
+        when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME))
+                .thenReturn(capaExpected);
+
+        DeviceWiphyCapabilities capaActual =
+                mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME);
+        assertEquals(capaExpected, capaActual);
+    }
+
     // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it
     // matches the provided frequency set and ssid set.
     private class ScanMatcher implements ArgumentMatcher<SingleScanSettings> {