Merge "Update clock to 2x2" into sc-dev am: 5fb31dd756 am: 264a7e92ba

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13439807

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I5d46edcbd4908a7f3ebe02a6620008a55a44372a
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index cdf5df6c..30ed7de 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -8,6 +8,7 @@
                cmds/input/
                cmds/uinput/
                core/jni/
+               libs/hwui/
                libs/input/
                native/
                services/core/jni/
diff --git a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
index 9e519f7..1d94d7e 100644
--- a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
+++ b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
@@ -178,7 +178,7 @@
             // For testing, just disable enforcement to avoid hooking up to compat framework
             ParseTypeImpl(ParseInput.Callback { _, _, _ -> false })
         }
-        val parser = ParsingPackageUtils(false, null, null,
+        val parser = ParsingPackageUtils(false, null, null, emptyList(),
             object : ParsingPackageUtils.Callback {
                 override fun hasFeature(feature: String) = true
 
diff --git a/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl
new file mode 100644
index 0000000..3d50d14
--- /dev/null
+++ b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl
@@ -0,0 +1,21 @@
+/**
+ * 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.media;
+
+/** {@hide} */
+interface IMediaCommunicationService {
+}
+
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 60dea07..5773e4d 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -38,6 +38,7 @@
     static_libs: [
         "exoplayer2-extractor",
         "mediatranscoding_aidl_interface-java",
+        "modules-utils-build",
     ],
     jarjar_rules: "jarjar_rules.txt",
 
@@ -52,6 +53,7 @@
     visibility: [
         "//frameworks/av/apex:__subpackages__",
         "//frameworks/base", // For framework-all
+        "//frameworks/base/apex/media/service",
     ],
 }
 
@@ -80,6 +82,7 @@
         "java/android/media/Session2CommandGroup.java",
         "java/android/media/Session2Link.java",
         "java/android/media/Session2Token.java",
+        "java/android/media/MediaCommunicationManager.java",
     ],
     path: "java",
 }
diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt
index 2543a9c..8b9990f 100644
--- a/apex/media/framework/api/current.txt
+++ b/apex/media/framework/api/current.txt
@@ -28,6 +28,9 @@
     ctor public ApplicationMediaCapabilities.FormatNotFoundException(@NonNull String);
   }
 
+  public class MediaCommunicationManager {
+  }
+
   public class MediaController2 implements java.lang.AutoCloseable {
     method public void cancelSessionCommand(@NonNull Object);
     method public void close();
diff --git a/apex/media/framework/jarjar_rules.txt b/apex/media/framework/jarjar_rules.txt
index d89d9d3..eb71fdd 100644
--- a/apex/media/framework/jarjar_rules.txt
+++ b/apex/media/framework/jarjar_rules.txt
@@ -1 +1,2 @@
+rule com.android.modules.utils.** android.media.internal.utils.@1
 rule com.google.android.exoplayer2.** android.media.internal.exo.@1
diff --git a/apex/media/framework/java/android/media/MediaCommunicationManager.java b/apex/media/framework/java/android/media/MediaCommunicationManager.java
new file mode 100644
index 0000000..b8065ef
--- /dev/null
+++ b/apex/media/framework/java/android/media/MediaCommunicationManager.java
@@ -0,0 +1,49 @@
+/*
+ * 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.media;
+
+import android.annotation.NonNull;
+import android.annotation.SystemService;
+import android.content.Context;
+
+import com.android.modules.utils.build.SdkLevel;
+
+/**
+ * Provides support for interacting with {@link android.media.MediaSession2 MediaSession2s}
+ * that applications have published to express their ongoing media playback state.
+ */
+// TODO: Add notifySession2Created() and sendMessage().
+@SystemService(Context.MEDIA_COMMUNICATION_SERVICE)
+public class MediaCommunicationManager {
+    private static final String TAG = "MediaCommunicationManager";
+
+    private final Context mContext;
+    private final IMediaCommunicationService mService;
+
+    /**
+     * @hide
+     */
+    public MediaCommunicationManager(@NonNull Context context) {
+        if (!SdkLevel.isAtLeastS()) {
+            throw new UnsupportedOperationException("Android version must be S or greater.");
+        }
+        mContext = context;
+        mService = IMediaCommunicationService.Stub.asInterface(
+                MediaFrameworkInitializer.getMediaServiceManager()
+                .getMediaCommunicationServiceRegisterer()
+                .get());
+    }
+}
diff --git a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
index 813ad7b..9332835 100644
--- a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
+++ b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
@@ -19,10 +19,11 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.SystemApi.Client;
-import android.media.MediaTranscodeManager;
 import android.app.SystemServiceRegistry;
 import android.content.Context;
 
+import com.android.modules.utils.build.SdkLevel;
+
 /**
  * Class for performing registration for all media services on com.android.media apex.
  *
@@ -74,5 +75,12 @@
                 MediaTranscodeManager.class,
                 context -> new MediaTranscodeManager(context)
         );
+        if (SdkLevel.isAtLeastS()) {
+            SystemServiceRegistry.registerContextAwareService(
+                    Context.MEDIA_COMMUNICATION_SERVICE,
+                    MediaCommunicationManager.class,
+                    context -> new MediaCommunicationManager(context)
+            );
+        }
     }
 }
diff --git a/apex/media/service/Android.bp b/apex/media/service/Android.bp
new file mode 100644
index 0000000..5b24cfa
--- /dev/null
+++ b/apex/media/service/Android.bp
@@ -0,0 +1,41 @@
+// 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.
+filegroup {
+    name: "service-media-s-sources",
+    srcs: [
+      "java/**/*.java",
+    ],
+    path: "java",
+    visibility: ["//frameworks/base/services"], // TODO(b/177640454): Should be private.
+}
+
+java_sdk_library {
+    name: "service-media-s",
+    permitted_packages: [
+        "com.android.server.media",
+    ],
+    defaults: ["framework-system-server-module-defaults"],
+    srcs: [
+        ":service-media-s-sources",
+    ],
+    libs: [
+        "updatable-media",
+    ],
+    sdk_version: "system_server_current",
+    min_sdk_version: "29", // TODO: We may need to bump this at some point.
+    apex_available: [
+        "com.android.media",
+    ],
+}
+
diff --git a/apex/media/service/api/current.txt b/apex/media/service/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/service/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/api/removed.txt b/apex/media/service/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/service/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/api/system-server-current.txt b/apex/media/service/api/system-server-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/service/api/system-server-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/api/system-server-removed.txt b/apex/media/service/api/system-server-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/service/api/system-server-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
new file mode 100644
index 0000000..0468fdf
--- /dev/null
+++ b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
@@ -0,0 +1,41 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+import android.media.IMediaCommunicationService;
+
+import com.android.server.SystemService;
+
+/**
+ * A system service that managers {@link android.media.MediaSession2} creations
+ * and their ongoing media playback state.
+ * @hide
+ */
+public class MediaCommunicationService extends SystemService {
+
+    public MediaCommunicationService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.MEDIA_COMMUNICATION_SERVICE, new Stub());
+    }
+
+    private class Stub extends IMediaCommunicationService.Stub {
+    }
+}
diff --git a/core/api/current.txt b/core/api/current.txt
index b49e724..8c4e785d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10374,6 +10374,7 @@
     field public static final String LAUNCHER_APPS_SERVICE = "launcherapps";
     field public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
     field public static final String LOCATION_SERVICE = "location";
+    field public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
     field public static final String MEDIA_METRICS_SERVICE = "media_metrics";
     field public static final String MEDIA_PROJECTION_SERVICE = "media_projection";
     field public static final String MEDIA_ROUTER_SERVICE = "media_router";
@@ -15771,6 +15772,7 @@
     method @NonNull public static android.graphics.RenderEffect createColorFilterEffect(@NonNull android.graphics.ColorFilter);
     method @NonNull public static android.graphics.RenderEffect createOffsetEffect(float, float);
     method @NonNull public static android.graphics.RenderEffect createOffsetEffect(float, float, @NonNull android.graphics.RenderEffect);
+    method @NonNull public static android.graphics.RenderEffect createShaderEffect(@NonNull android.graphics.Shader);
   }
 
   public final class RenderNode {
@@ -16799,6 +16801,18 @@
 
 package android.hardware {
 
+  public abstract class Battery {
+    ctor public Battery();
+    method @FloatRange(from=-1.0F, to=1.0f) public abstract float getCapacity();
+    method public abstract int getStatus();
+    method public abstract boolean hasBattery();
+    field public static final int STATUS_CHARGING = 2; // 0x2
+    field public static final int STATUS_DISCHARGING = 3; // 0x3
+    field public static final int STATUS_FULL = 5; // 0x5
+    field public static final int STATUS_NOT_CHARGING = 4; // 0x4
+    field public static final int STATUS_UNKNOWN = 1; // 0x1
+  }
+
   @Deprecated public class Camera {
     method @Deprecated public final void addCallbackBuffer(byte[]);
     method @Deprecated public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
@@ -18499,6 +18513,7 @@
   public final class InputManager {
     method public android.view.InputDevice getInputDevice(int);
     method public int[] getInputDeviceIds();
+    method public float getMaximumObscuringOpacityForTouch();
     method public void registerInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener, android.os.Handler);
     method public void unregisterInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener);
     method @Nullable public android.view.VerifiedInputEvent verifyInputEvent(@NonNull android.view.InputEvent);
@@ -46366,6 +46381,7 @@
 
   public final class InputDevice implements android.os.Parcelable {
     method public int describeContents();
+    method @NonNull public android.hardware.Battery getBattery();
     method public int getControllerNumber();
     method public String getDescriptor();
     method public static android.view.InputDevice getDevice(int);
@@ -46420,6 +46436,7 @@
     field public static final int SOURCE_MOUSE = 8194; // 0x2002
     field public static final int SOURCE_MOUSE_RELATIVE = 131076; // 0x20004
     field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
+    field public static final int SOURCE_SENSOR = 67108864; // 0x4000000
     field public static final int SOURCE_STYLUS = 16386; // 0x4002
     field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
     field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 2b9f171..0f49dc5 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -103,6 +103,7 @@
   }
 
   public class MediaServiceManager {
+    method @NonNull public android.media.MediaServiceManager.ServiceRegisterer getMediaCommunicationServiceRegisterer();
     method @NonNull public android.media.MediaServiceManager.ServiceRegisterer getMediaSessionServiceRegisterer();
     method @NonNull public android.media.MediaServiceManager.ServiceRegisterer getMediaTranscodingServiceRegisterer();
   }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f40bf5d..b7a876a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4635,6 +4635,7 @@
   public static class AudioAttributes.Builder {
     method public android.media.AudioAttributes.Builder addBundle(@NonNull android.os.Bundle);
     method public android.media.AudioAttributes.Builder setCapturePreset(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) public android.media.AudioAttributes.Builder setHotwordMode();
     method public android.media.AudioAttributes.Builder setInternalCapturePreset(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioAttributes.Builder setSystemUsage(int);
   }
@@ -9845,6 +9846,7 @@
     method public void onNotificationDirectReplied(@NonNull String);
     method @Nullable public abstract android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification);
     method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel);
+    method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel, @NonNull android.service.notification.NotificationListenerService.RankingMap);
     method public void onNotificationExpansionChanged(@NonNull String, boolean, boolean);
     method public abstract void onNotificationSnoozedUntilContext(@NonNull android.service.notification.StatusBarNotification, @NonNull String);
     method public void onNotificationVisibilityChanged(@NonNull String, boolean);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 445824a..a3d8254 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -401,10 +401,10 @@
     field public static final int CODE_MANAGED_USERS_NOT_SUPPORTED = 9; // 0x9
     field public static final int CODE_NONSYSTEM_USER_EXISTS = 5; // 0x5
     field public static final int CODE_NOT_SYSTEM_USER = 7; // 0x7
-    field public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc
+    field @Deprecated public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12; // 0xc
     field public static final int CODE_OK = 0; // 0x0
     field public static final int CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS = 15; // 0xf
-    field public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe
+    field @Deprecated public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe
     field public static final int CODE_SYSTEM_USER = 10; // 0xa
     field public static final int CODE_USER_HAS_PROFILE_OWNER = 2; // 0x2
     field public static final int CODE_USER_NOT_RUNNING = 3; // 0x3
@@ -944,9 +944,8 @@
 
   public final class InputManager {
     method public int getBlockUntrustedTouchesMode(@NonNull android.content.Context);
-    method public float getMaximumObscuringOpacityForTouch(@NonNull android.content.Context);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setBlockUntrustedTouchesMode(@NonNull android.content.Context, int);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, float);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(float);
     field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL
   }
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 77542bd..09585e0 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -59,6 +59,7 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageUserState;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
@@ -70,6 +71,12 @@
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VersionedPackage;
 import android.content.pm.dex.ArtManager;
+import android.content.pm.parsing.PackageInfoWithoutStateUtils;
+import android.content.pm.parsing.ParsingPackage;
+import android.content.pm.parsing.ParsingPackageUtils;
+import android.content.pm.parsing.result.ParseInput;
+import android.content.pm.parsing.result.ParseResult;
+import android.content.pm.parsing.result.ParseTypeImpl;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
@@ -115,6 +122,7 @@
 
 import libcore.util.EmptyArray;
 
+import java.io.File;
 import java.lang.ref.WeakReference;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
@@ -2045,6 +2053,31 @@
         return info.loadLabel(this);
     }
 
+    @Nullable
+    public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath,
+            @PackageInfoFlags int flags) {
+        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) == 0) {
+            // Caller expressed no opinion about what encryption
+            // aware/unaware components they want to see, so match both
+            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
+                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+        }
+
+        boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0
+                || (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0;
+
+        ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset();
+        ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input,
+                new File(archiveFilePath), 0, getPermissionManager().getSplitPermissions(),
+                collectCertificates);
+        if (result.isError()) {
+            return null;
+        }
+        return PackageInfoWithoutStateUtils.generate(result.getResult(), null, flags, 0, 0, null,
+                new PackageUserState(), UserHandle.getCallingUserId());
+    }
+
     @Override
     public int installExistingPackage(String packageName) throws NameNotFoundException {
         return installExistingPackage(packageName, INSTALL_REASON_UNKNOWN);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ada703b..e84d4a5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -453,59 +453,6 @@
             "android.app.action.PROVISION_FINANCED_DEVICE";
 
     /**
-     * Activity action: Starts the provisioning flow which sets up a managed device.
-     * Must be started with {@link android.app.Activity#startActivityForResult(Intent, int)}.
-     *
-     * <p>NOTE: This is only supported on split system user devices, and puts the device into a
-     * management state that is distinct from that reached by
-     * {@link #ACTION_PROVISION_MANAGED_DEVICE} - specifically the device owner runs on the system
-     * user, and only has control over device-wide policies, not individual users and their data.
-     * The primary benefit is that multiple non-system users are supported when provisioning using
-     * this form of device management.
-     *
-     * <p>During device owner provisioning a device admin app is set as the owner of the device.
-     * A device owner has full control over the device. The device owner can not be modified by the
-     * user.
-     *
-     * <p>A typical use case would be a device that is owned by a company, but used by either an
-     * employee or client.
-     *
-     * <p>An intent with this action can be sent only on an unprovisioned device.
-     * It is possible to check if provisioning is allowed or not by querying the method
-     * {@link #isProvisioningAllowed(String)}.
-     *
-     * <p>The intent contains the following extras:
-     * <ul>
-     * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_MAIN_COLOR}, optional</li>
-     * </ul>
-     *
-     * <p>When device owner provisioning has completed, an intent of the type
-     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcast to the
-     * device owner.
-     *
-     * <p>From version {@link android.os.Build.VERSION_CODES#O}, when device owner provisioning has
-     * completed, along with the above broadcast, activity intent
-     * {@link #ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the device owner.
-     *
-     * <p>If provisioning fails, the device is factory reset.
-     *
-     * <p>A result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part
-     * of the provisioning flow was successful, although this doesn't guarantee the full flow will
-     * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies
-     * that the user backed-out of provisioning, or some precondition for provisioning wasn't met.
-     *
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE
-        = "android.app.action.PROVISION_MANAGED_SHAREABLE_DEVICE";
-
-    /**
      * Activity action: Finalizes management provisioning, should be used after user-setup
      * has been completed and {@link #getUserProvisioningState()} returns one of:
      * <ul>
@@ -1990,8 +1937,8 @@
      * Result code for {@link #checkProvisioningPreCondition}.
      *
      * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE},
-     * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when provisioning is allowed.
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} and {@link #ACTION_PROVISION_MANAGED_USER}
+     * when provisioning is allowed.
      *
      * @hide
      */
@@ -2001,9 +1948,8 @@
     /**
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the device already has a device
-     * owner.
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the device already has a
+     * device owner.
      *
      * @hide
      */
@@ -2013,9 +1959,8 @@
     /**
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE},
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user has a profile owner and for
-     * {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set.
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the user has a profile owner
+     *  and for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the profile owner is already set.
      *
      * @hide
      */
@@ -2025,8 +1970,7 @@
     /**
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} when the user isn't running.
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} when the user isn't running.
      *
      * @hide
      */
@@ -2036,9 +1980,8 @@
     /**
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE},
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the device has already been setup and
-     * for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup.
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} if the device has already been
+     * setup and for {@link #ACTION_PROVISION_MANAGED_USER} if the user has already been setup.
      *
      * @hide
      */
@@ -2064,8 +2007,7 @@
     /**
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} if the user is not a system user.
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} if the user is not a system user.
      *
      * @hide
      */
@@ -2075,9 +2017,8 @@
     /**
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE},
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} and {@link #ACTION_PROVISION_MANAGED_USER}
-     * when the device is a watch and is already paired.
+     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE} and
+     * {@link #ACTION_PROVISION_MANAGED_USER} when the device is a watch and is already paired.
      *
      * @hide
      */
@@ -2121,14 +2062,11 @@
 
     /**
      * TODO (b/137101239): clean up split system user codes
-     * Result code for {@link #checkProvisioningPreCondition}.
-     *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_USER} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices not running with split system
-     * user.
      *
      * @hide
-     */
+     * @deprecated not used anymore but can't be removed since it's a @TestApi.
+     **/
+    @Deprecated
     @TestApi
     public static final int CODE_NOT_SYSTEM_USER_SPLIT = 12;
 
@@ -2136,8 +2074,7 @@
      * Result code for {@link #checkProvisioningPreCondition}.
      *
      * <p>Returned for {@link #ACTION_PROVISION_MANAGED_DEVICE},
-     * {@link #ACTION_PROVISION_MANAGED_PROFILE}, {@link #ACTION_PROVISION_MANAGED_USER} and
-     * {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE} on devices which do not support device
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} on devices which do not support device
      * admins.
      *
      * @hide
@@ -2149,11 +2086,10 @@
      * TODO (b/137101239): clean up split system user codes
      * Result code for {@link #checkProvisioningPreCondition}.
      *
-     * <p>Returned for {@link #ACTION_PROVISION_MANAGED_PROFILE} when the device the user is a
-     * system user on a split system user device.
-     *
      * @hide
+     * @deprecated not used anymore but can't be removed since it's a @TestApi.
      */
+    @Deprecated
     @TestApi
     public static final int CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14;
 
@@ -7147,17 +7083,9 @@
     }
 
     /**
+     * TODO (b/137101239): remove this method in follow-up CL
+     * since it's only used for split system user.
      * Called by a device owner to set whether all users created on the device should be ephemeral.
-     * <p>
-     * The system user is exempt from this policy - it is never ephemeral.
-     * <p>
-     * The calling device admin must be the device owner. If it is not, a security exception will be
-     * thrown.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param forceEphemeralUsers If true, all the existing users will be deleted and all
-     *            subsequently created users will be ephemeral.
-     * @throws SecurityException if {@code admin} is not a device owner.
      * @hide
      */
     public void setForceEphemeralUsers(
@@ -7173,6 +7101,8 @@
     }
 
     /**
+     * TODO (b/137101239): remove this method in follow-up CL
+     * since it's only used for split system user.
      * @return true if all users are created ephemeral.
      * @throws SecurityException if {@code admin} is not a device owner.
      * @hide
@@ -10731,9 +10661,7 @@
      * profile or user, setting the given package as owner.
      *
      * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE},
-     *        {@link #ACTION_PROVISION_MANAGED_PROFILE},
-     *        {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE},
-     *        {@link #ACTION_PROVISION_MANAGED_USER}
+     *        {@link #ACTION_PROVISION_MANAGED_PROFILE}
      * @param packageName The package of the component that would be set as device, user, or profile
      *        owner.
      * @return A {@link ProvisioningPreCondition} value indicating whether provisioning is allowed.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 7eda50e..ea7e5ea 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3198,6 +3198,61 @@
     }
 
     /**
+     * Register a callback to receive events whenever the bluetooth stack goes down and back up,
+     * e.g. in the event the bluetooth is turned off/on via settings.
+     *
+     * If the bluetooth stack is currently up, there will not be an initial callback call.
+     * You can use the return value as an indication of this being the case.
+     *
+     * Callbacks will be delivered on a binder thread.
+     *
+     * @return whether bluetooth is already up currently
+     *
+     * @hide
+     */
+    public boolean registerServiceLifecycleCallback(ServiceLifecycleCallback callback) {
+        return getBluetoothService(callback.mRemote) != null;
+    }
+
+    /**
+     * Unregister a callback registered via {@link #registerServiceLifecycleCallback}
+     *
+     * @hide
+     */
+    public void unregisterServiceLifecycleCallback(ServiceLifecycleCallback callback) {
+        removeServiceStateCallback(callback.mRemote);
+    }
+
+    /**
+     * A callback for {@link #registerServiceLifecycleCallback}
+     *
+     * @hide
+     */
+    public abstract static class ServiceLifecycleCallback {
+
+        /** Called when the bluetooth stack is up */
+        public abstract void onBluetoothServiceUp();
+
+        /** Called when the bluetooth stack is down */
+        public abstract void onBluetoothServiceDown();
+
+        IBluetoothManagerCallback mRemote = new IBluetoothManagerCallback.Stub() {
+            @Override
+            public void onBluetoothServiceUp(IBluetooth bluetoothService) {
+                ServiceLifecycleCallback.this.onBluetoothServiceUp();
+            }
+
+            @Override
+            public void onBluetoothServiceDown() {
+                ServiceLifecycleCallback.this.onBluetoothServiceDown();
+            }
+
+            @Override
+            public void onBrEdrDown() {}
+        };
+    }
+
+    /**
      * Starts a scan for Bluetooth LE devices.
      *
      * <p>Results of the scan are reported using the
diff --git a/core/java/android/companion/Association.java b/core/java/android/companion/Association.java
index 17bf11b..b060ce2 100644
--- a/core/java/android/companion/Association.java
+++ b/core/java/android/companion/Association.java
@@ -23,6 +23,7 @@
 
 import com.android.internal.util.DataClass;
 
+import java.util.Date;
 import java.util.Objects;
 
 /**
@@ -38,16 +39,21 @@
     private final @NonNull String mDeviceMacAddress;
     private final @NonNull String mPackageName;
     private final @Nullable String mDeviceProfile;
-    private final boolean mKeepProfilePrivilegesWhenDeviceAway;
+    private final boolean mNotifyOnDeviceNearby;
+    private final long mTimeApprovedMs;
 
     /** @hide */
     public int getUserId() {
         return mUserId;
     }
 
+    private String timeApprovedMsToString() {
+        return new Date(mTimeApprovedMs).toString();
+    }
 
 
-    // Code below generated by codegen v1.0.21.
+
+    // Code below generated by codegen v1.0.22.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -71,7 +77,8 @@
             @NonNull String deviceMacAddress,
             @NonNull String packageName,
             @Nullable String deviceProfile,
-            boolean keepProfilePrivilegesWhenDeviceAway) {
+            boolean notifyOnDeviceNearby,
+            long timeApprovedMs) {
         this.mUserId = userId;
         com.android.internal.util.AnnotationValidations.validate(
                 UserIdInt.class, null, mUserId);
@@ -82,7 +89,8 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mPackageName);
         this.mDeviceProfile = deviceProfile;
-        this.mKeepProfilePrivilegesWhenDeviceAway = keepProfilePrivilegesWhenDeviceAway;
+        this.mNotifyOnDeviceNearby = notifyOnDeviceNearby;
+        this.mTimeApprovedMs = timeApprovedMs;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -103,8 +111,13 @@
     }
 
     @DataClass.Generated.Member
-    public boolean isKeepProfilePrivilegesWhenDeviceAway() {
-        return mKeepProfilePrivilegesWhenDeviceAway;
+    public boolean isNotifyOnDeviceNearby() {
+        return mNotifyOnDeviceNearby;
+    }
+
+    @DataClass.Generated.Member
+    public long getTimeApprovedMs() {
+        return mTimeApprovedMs;
     }
 
     @Override
@@ -118,7 +131,8 @@
                 "deviceMacAddress = " + mDeviceMacAddress + ", " +
                 "packageName = " + mPackageName + ", " +
                 "deviceProfile = " + mDeviceProfile + ", " +
-                "keepProfilePrivilegesWhenDeviceAway = " + mKeepProfilePrivilegesWhenDeviceAway +
+                "notifyOnDeviceNearby = " + mNotifyOnDeviceNearby + ", " +
+                "timeApprovedMs = " + timeApprovedMsToString() +
         " }";
     }
 
@@ -139,7 +153,8 @@
                 && Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress)
                 && Objects.equals(mPackageName, that.mPackageName)
                 && Objects.equals(mDeviceProfile, that.mDeviceProfile)
-                && mKeepProfilePrivilegesWhenDeviceAway == that.mKeepProfilePrivilegesWhenDeviceAway;
+                && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby
+                && mTimeApprovedMs == that.mTimeApprovedMs;
     }
 
     @Override
@@ -153,7 +168,8 @@
         _hash = 31 * _hash + Objects.hashCode(mDeviceMacAddress);
         _hash = 31 * _hash + Objects.hashCode(mPackageName);
         _hash = 31 * _hash + Objects.hashCode(mDeviceProfile);
-        _hash = 31 * _hash + Boolean.hashCode(mKeepProfilePrivilegesWhenDeviceAway);
+        _hash = 31 * _hash + Boolean.hashCode(mNotifyOnDeviceNearby);
+        _hash = 31 * _hash + Long.hashCode(mTimeApprovedMs);
         return _hash;
     }
 
@@ -164,13 +180,14 @@
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         byte flg = 0;
-        if (mKeepProfilePrivilegesWhenDeviceAway) flg |= 0x10;
+        if (mNotifyOnDeviceNearby) flg |= 0x10;
         if (mDeviceProfile != null) flg |= 0x8;
         dest.writeByte(flg);
         dest.writeInt(mUserId);
         dest.writeString(mDeviceMacAddress);
         dest.writeString(mPackageName);
         if (mDeviceProfile != null) dest.writeString(mDeviceProfile);
+        dest.writeLong(mTimeApprovedMs);
     }
 
     @Override
@@ -185,11 +202,12 @@
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         byte flg = in.readByte();
-        boolean keepProfilePrivilegesWhenDeviceAway = (flg & 0x10) != 0;
+        boolean notifyOnDeviceNearby = (flg & 0x10) != 0;
         int userId = in.readInt();
         String deviceMacAddress = in.readString();
         String packageName = in.readString();
         String deviceProfile = (flg & 0x8) == 0 ? null : in.readString();
+        long timeApprovedMs = in.readLong();
 
         this.mUserId = userId;
         com.android.internal.util.AnnotationValidations.validate(
@@ -201,7 +219,8 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mPackageName);
         this.mDeviceProfile = deviceProfile;
-        this.mKeepProfilePrivilegesWhenDeviceAway = keepProfilePrivilegesWhenDeviceAway;
+        this.mNotifyOnDeviceNearby = notifyOnDeviceNearby;
+        this.mTimeApprovedMs = timeApprovedMs;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -221,10 +240,10 @@
     };
 
     @DataClass.Generated(
-            time = 1606940835778L,
-            codegenVersion = "1.0.21",
+            time = 1611795283642L,
+            codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/companion/Association.java",
-            inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate final  boolean mKeepProfilePrivilegesWhenDeviceAway\npublic  int getUserId()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)")
+            inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate final  boolean mNotifyOnDeviceNearby\nprivate final  long mTimeApprovedMs\npublic  int getUserId()\nprivate  java.lang.String timeApprovedMsToString()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index 083ce96..102c98f 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -55,6 +55,8 @@
         genBuilder = false)
 public final class AssociationRequest implements Parcelable {
 
+    private static final String LOG_TAG = AssociationRequest.class.getSimpleName();
+
     /**
      * Device profile: watch.
      *
@@ -115,13 +117,6 @@
         mDeviceProfilePrivilegesDescription = desc;
     }
 
-    private void onConstructed() {
-        if (mDeviceProfile != null
-                && !Objects.equals(mDeviceProfile, DEVICE_PROFILE_WATCH)) {
-            throw new IllegalArgumentException("Invalid device profile: " + mDeviceProfile);
-        }
-    }
-
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean isSingleDevice() {
@@ -252,7 +247,7 @@
         this.mCallingPackage = callingPackage;
         this.mDeviceProfilePrivilegesDescription = deviceProfilePrivilegesDescription;
 
-        onConstructed();
+        // onConstructed(); // You can define this method to get a callback
     }
 
     /**
@@ -386,7 +381,7 @@
         this.mCallingPackage = callingPackage;
         this.mDeviceProfilePrivilegesDescription = deviceProfilePrivilegesDescription;
 
-        onConstructed();
+        // onConstructed(); // You can define this method to get a callback
     }
 
     @DataClass.Generated.Member
@@ -404,10 +399,10 @@
     };
 
     @DataClass.Generated(
-            time = 1610132130920L,
+            time = 1611692924843L,
             codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java",
-            inputSignatures = "public static final  java.lang.String DEVICE_PROFILE_WATCH\nprivate  boolean mSingleDevice\nprivate @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\npublic  void setCallingPackage(java.lang.String)\npublic  void setDeviceProfilePrivilegesDescription(java.lang.String)\nprivate  void onConstructed()\npublic @android.compat.annotation.UnsupportedAppUsage boolean isSingleDevice()\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false)")
+            inputSignatures = "private static final  java.lang.String LOG_TAG\npublic static final  java.lang.String DEVICE_PROFILE_WATCH\nprivate  boolean mSingleDevice\nprivate @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\npublic  void setCallingPackage(java.lang.String)\npublic  void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic @android.compat.annotation.UnsupportedAppUsage boolean isSingleDevice()\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 527d8df..95d3515 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -49,4 +49,6 @@
     void registerDevicePresenceListenerService(in String packageName, in String deviceAddress);
 
     void unregisterDevicePresenceListenerService(in String packageName, in String deviceAddress);
+
+    boolean canPairWithoutPrompt(in String packageName, in String deviceMacAddress, int userId);
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index d7dc86a..46d8900 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -63,7 +63,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.system.Int32Ref;
+import android.system.Int64Ref;
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.Log;
@@ -4050,7 +4050,7 @@
         // Convert to Point, since that's what the API is defined as
         final Bundle opts = new Bundle();
         opts.putParcelable(EXTRA_SIZE, new Point(size.getWidth(), size.getHeight()));
-        final Int32Ref orientation = new Int32Ref(0);
+        final Int64Ref orientation = new Int64Ref(0);
 
         Bitmap bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> {
             final AssetFileDescriptor afd = content.openTypedAssetFile(uri, "image/*", opts,
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6a2329e..125b5ff 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4371,6 +4371,16 @@
     public static final String BIOMETRIC_SERVICE = "biometric";
 
     /**
+     * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.media.MediaCommunicationManager}
+     * for managing {@link android.media.MediaSession2}.
+     *
+     * @see #getSystemService(String)
+     * @see android.media.MediaCommunicationManager
+     */
+    public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.media.MediaRouter} for controlling and managing
      * routing of media.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9ae9c25..2774c9c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -48,12 +48,6 @@
 import android.content.IntentFilter;
 import android.content.IntentSender;
 import android.content.pm.dex.ArtManager;
-import android.content.pm.parsing.PackageInfoWithoutStateUtils;
-import android.content.pm.parsing.ParsingPackage;
-import android.content.pm.parsing.ParsingPackageUtils;
-import android.content.pm.parsing.result.ParseInput;
-import android.content.pm.parsing.result.ParseResult;
-import android.content.pm.parsing.result.ParseTypeImpl;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Rect;
@@ -82,7 +76,6 @@
 
 import dalvik.system.VMRuntime;
 
-import java.io.File;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.security.cert.Certificate;
@@ -6761,25 +6754,8 @@
     @Nullable
     public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath,
             @PackageInfoFlags int flags) {
-        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
-                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) == 0) {
-            // Caller expressed no opinion about what encryption
-            // aware/unaware components they want to see, so match both
-            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
-                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-        }
-
-        boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0
-                || (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0;
-
-        ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset();
-        ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input,
-                new File(archiveFilePath), 0, collectCertificates);
-        if (result.isError()) {
-            return null;
-        }
-        return PackageInfoWithoutStateUtils.generate(result.getResult(), null, flags, 0, 0, null,
-                new PackageUserState(), UserHandle.getCallingUserId());
+        throw new UnsupportedOperationException(
+                "getPackageArchiveInfo() not implemented in subclass");
     }
 
     /**
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index b054304..8fbf287 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -34,7 +34,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StyleableRes;
-import android.app.ActivityThread;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
@@ -222,13 +221,15 @@
     private static final int MAX_FILE_NAME_SIZE = 223;
 
     /**
-     * @see #parseDefault(ParseInput, File, int, boolean)
+     * @see #parseDefault(ParseInput, File, int, List, boolean)
      */
     @NonNull
     public static ParseResult<ParsingPackage> parseDefaultOneTime(File file,
-            @ParseFlags int parseFlags, boolean collectCertificates) {
+            @ParseFlags int parseFlags,
+            @NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions,
+            boolean collectCertificates) {
         ParseInput input = ParseTypeImpl.forDefaultParsing().reset();
-        return parseDefault(input, file, parseFlags, collectCertificates);
+        return parseDefault(input, file, parseFlags, splitPermissions, collectCertificates);
     }
 
     /**
@@ -238,28 +239,32 @@
      */
     @NonNull
     public static ParseResult<ParsingPackage> parseDefault(ParseInput input, File file,
-            @ParseFlags int parseFlags, boolean collectCertificates) {
+            @ParseFlags int parseFlags,
+            @NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions,
+            boolean collectCertificates) {
         ParseResult<ParsingPackage> result;
 
-        ParsingPackageUtils parser = new ParsingPackageUtils(false, null, null, new Callback() {
-            @Override
-            public boolean hasFeature(String feature) {
-                // Assume the device doesn't support anything. This will affect permission parsing
-                // and will force <uses-permission/> declarations to include all requiredNotFeature
-                // permissions and exclude all requiredFeature permissions. This mirrors the old
-                // behavior.
-                return false;
-            }
+        ParsingPackageUtils parser = new ParsingPackageUtils(false, null, null, splitPermissions,
+                new Callback() {
+                    @Override
+                    public boolean hasFeature(String feature) {
+                        // Assume the device doesn't support anything. This will affect permission
+                        // parsing and will force <uses-permission/> declarations to include all
+                        // requiredNotFeature permissions and exclude all requiredFeature
+                        // permissions. This mirrors the old behavior.
+                        return false;
+                    }
 
-            @Override
-            public ParsingPackage startParsingPackage(
-                    @NonNull String packageName,
-                    @NonNull String baseApkPath,
-                    @NonNull String path,
-                    @NonNull TypedArray manifestArray, boolean isCoreApp) {
-                return new ParsingPackageImpl(packageName, baseApkPath, path, manifestArray);
-            }
-        });
+                    @Override
+                    public ParsingPackage startParsingPackage(
+                            @NonNull String packageName,
+                            @NonNull String baseApkPath,
+                            @NonNull String path,
+                            @NonNull TypedArray manifestArray, boolean isCoreApp) {
+                        return new ParsingPackageImpl(packageName, baseApkPath, path,
+                                manifestArray);
+                    }
+                });
         try {
             result = parser.parsePackage(input, file, parseFlags);
             if (result.isError()) {
@@ -290,13 +295,18 @@
     private boolean mOnlyCoreApps;
     private String[] mSeparateProcesses;
     private DisplayMetrics mDisplayMetrics;
+    @NonNull
+    private List<PermissionManager.SplitPermissionInfo> mSplitPermissionInfos;
     private Callback mCallback;
 
     public ParsingPackageUtils(boolean onlyCoreApps, String[] separateProcesses,
-            DisplayMetrics displayMetrics, @NonNull Callback callback) {
+            DisplayMetrics displayMetrics,
+            @NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions,
+            @NonNull Callback callback) {
         mOnlyCoreApps = onlyCoreApps;
         mSeparateProcesses = separateProcesses;
         mDisplayMetrics = displayMetrics;
+        mSplitPermissionInfos = splitPermissions;
         mCallback = callback;
     }
 
@@ -2743,14 +2753,10 @@
         }
     }
 
-    private static void convertSplitPermissions(ParsingPackage pkg) {
-        final List<PermissionManager.SplitPermissionInfo> splitPermissions =
-                ActivityThread.currentApplication().getSystemService(PermissionManager.class)
-                        .getSplitPermissions();
-
-        final int listSize = splitPermissions.size();
+    private void convertSplitPermissions(ParsingPackage pkg) {
+        final int listSize = mSplitPermissionInfos.size();
         for (int is = 0; is < listSize; is++) {
-            final PermissionManager.SplitPermissionInfo spi = splitPermissions.get(is);
+            final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is);
             List<String> requestedPermissions = pkg.getRequestedPermissions();
             if (pkg.getTargetSdkVersion() >= spi.getTargetSdk()
                     || !requestedPermissions.contains(spi.getSplitPermission())) {
diff --git a/core/java/android/hardware/Battery.java b/core/java/android/hardware/Battery.java
new file mode 100644
index 0000000..24c8d76
--- /dev/null
+++ b/core/java/android/hardware/Battery.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.os.BatteryManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The Battery class is a representation of a single battery on a device.
+ */
+public abstract class Battery {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "STATUS_" }, value = {
+            STATUS_UNKNOWN,
+            STATUS_CHARGING,
+            STATUS_DISCHARGING,
+            STATUS_NOT_CHARGING,
+            STATUS_FULL
+    })
+    public @interface BatteryStatus {
+    }
+
+    /** Battery status is unknown. */
+    public static final int STATUS_UNKNOWN = BatteryManager.BATTERY_STATUS_UNKNOWN;
+    /** Battery is charging. */
+    public static final int STATUS_CHARGING = BatteryManager.BATTERY_STATUS_CHARGING;
+    /** Battery is discharging. */
+    public static final int STATUS_DISCHARGING = BatteryManager.BATTERY_STATUS_DISCHARGING;
+    /** Battery is connected to power but not charging. */
+    public static final int STATUS_NOT_CHARGING = BatteryManager.BATTERY_STATUS_NOT_CHARGING;
+    /** Battery is full. */
+    public static final int STATUS_FULL = BatteryManager.BATTERY_STATUS_FULL;
+
+    /**
+     * Check whether the hardware has a battery.
+     *
+     * @return True if the hardware has a battery, else false.
+     */
+    public abstract boolean hasBattery();
+
+    /**
+     * Get the battery status.
+     *
+     * @return the battery status.
+     */
+    public abstract @BatteryStatus int getStatus();
+
+    /**
+     * Get remaining battery capacity as float percentage [0.0f, 1.0f] of total capacity
+     * Returns -1 when battery capacity can't be read.
+     *
+     * @return the battery capacity.
+     */
+    public abstract @FloatRange(from = -1.0f, to = 1.0f) float getCapacity();
+}
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 4145a72..08b1e24 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -29,7 +29,6 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.os.RemoteException;
-import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.util.Slog;
 
@@ -47,6 +46,13 @@
     private static final String TAG = "BiometricManager";
 
     /**
+     * An ID that should match any biometric sensor on the device.
+     *
+     * @hide
+     */
+    public static final int SENSOR_ID_ANY = -1;
+
+    /**
      * No error detected.
      */
     public static final int BIOMETRIC_SUCCESS =
@@ -139,7 +145,7 @@
          *
          * <p>This corresponds to {@link KeyProperties#AUTH_BIOMETRIC_STRONG} during key generation.
          *
-         * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
+         * @see android.security.keystore.KeyGenParameterSpec.Builder
          */
         int BIOMETRIC_STRONG = 0x000F;
 
@@ -182,7 +188,7 @@
          * <p>This corresponds to {@link KeyProperties#AUTH_DEVICE_CREDENTIAL} during key
          * generation.
          *
-         * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
+         * @see android.security.keystore.KeyGenParameterSpec.Builder
          */
         int DEVICE_CREDENTIAL = 1 << 15;
     }
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 76cf9b9..4f6a7c7 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -36,7 +36,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.security.identity.IdentityCredential;
-import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.text.TextUtils;
 import android.util.Log;
@@ -325,7 +324,7 @@
          * request authentication with the proper set of authenticators (e.g. match the
          * authenticators specified during key generation).
          *
-         * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
+         * @see android.security.keystore.KeyGenParameterSpec.Builder
          * @see KeyProperties#AUTH_BIOMETRIC_STRONG
          * @see KeyProperties#AUTH_DEVICE_CREDENTIAL
          *
@@ -365,6 +364,21 @@
         }
 
         /**
+         * If set, authenticate using the biometric sensor with the given ID.
+         *
+         * @param sensorId The ID of a biometric sensor, or -1 to allow any sensor (default).
+         * @return This builder.
+         *
+         * @hide
+         */
+        @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+        @NonNull
+        public Builder setSensorId(int sensorId) {
+            mPromptInfo.setSensorId(sensorId);
+            return this;
+        }
+
+        /**
          * Creates a {@link BiometricPrompt}.
          *
          * @return An instance of {@link BiometricPrompt}.
@@ -589,7 +603,8 @@
      *
      * <p>Cryptographic operations in Android can be split into two categories: auth-per-use and
      * time-based. This is specified during key creation via the timeout parameter of the
-     * {@link KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)} API.
+     * {@code setUserAuthenticationParameters(int, int)} method of {@link
+     * android.security.keystore.KeyGenParameterSpec.Builder}.
      *
      * <p>CryptoObjects are used to unlock auth-per-use keys via
      * {@link BiometricPrompt#authenticate(CryptoObject, CancellationSignal, Executor,
@@ -778,6 +793,27 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AuthenticationCallback callback,
             int userId) {
+        authenticateUserForOperation(cancel, executor, callback, userId, 0 /* operationId */);
+    }
+
+    /**
+     * Authenticates for the given user and keystore operation.
+     *
+     * @param cancel An object that can be used to cancel authentication
+     * @param executor An executor to handle callback events
+     * @param callback An object to receive authentication events
+     * @param userId The user to authenticate
+     * @param operationId The keystore operation associated with authentication
+     *
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public void authenticateUserForOperation(
+            @NonNull CancellationSignal cancel,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull AuthenticationCallback callback,
+            int userId,
+            long operationId) {
         if (cancel == null) {
             throw new IllegalArgumentException("Must supply a cancellation signal");
         }
@@ -787,7 +823,7 @@
         if (callback == null) {
             throw new IllegalArgumentException("Must supply a callback");
         }
-        authenticateInternal(null /* crypto */, cancel, executor, callback, userId);
+        authenticateInternal(operationId, cancel, executor, callback, userId);
     }
 
     /**
@@ -912,11 +948,31 @@
         }
     }
 
-    private void authenticateInternal(@Nullable CryptoObject crypto,
+    private void authenticateInternal(
+            @Nullable CryptoObject crypto,
             @NonNull CancellationSignal cancel,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AuthenticationCallback callback,
             int userId) {
+
+        mCryptoObject = crypto;
+        final long operationId = crypto != null ? crypto.getOpId() : 0L;
+        authenticateInternal(operationId, cancel, executor, callback, userId);
+    }
+
+    private void authenticateInternal(
+            long operationId,
+            @NonNull CancellationSignal cancel,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull AuthenticationCallback callback,
+            int userId) {
+
+        // Ensure we don't return the wrong crypto object as an auth result.
+        if (mCryptoObject != null && mCryptoObject.getOpId() != operationId) {
+            Log.w(TAG, "CryptoObject operation ID does not match argument; setting field to null");
+            mCryptoObject = null;
+        }
+
         try {
             if (cancel.isCanceled()) {
                 Log.w(TAG, "Authentication already canceled");
@@ -925,13 +981,11 @@
                 cancel.setOnCancelListener(new OnAuthenticationCancelListener());
             }
 
-            mCryptoObject = crypto;
             mExecutor = executor;
             mAuthenticationCallback = callback;
-            final long operationId = crypto != null ? crypto.getOpId() : 0;
 
             final PromptInfo promptInfo;
-            if (crypto != null) {
+            if (operationId != 0L) {
                 // Allowed authenticators should default to BIOMETRIC_STRONG for crypto auth.
                 // Note that we use a new PromptInfo here so as to not overwrite the application's
                 // preference, since it is possible that the same prompt configuration be used
@@ -952,10 +1006,9 @@
 
         } catch (RemoteException e) {
             Log.e(TAG, "Remote exception while authenticating", e);
-            mExecutor.execute(() -> {
-                callback.onAuthenticationError(BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                        mContext.getString(R.string.biometric_error_hw_unavailable));
-            });
+            mExecutor.execute(() -> callback.onAuthenticationError(
+                    BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                    mContext.getString(R.string.biometric_error_hw_unavailable)));
         }
     }
 }
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index c2eff7d..0e99f31 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -40,6 +40,7 @@
     private @BiometricManager.Authenticators.Types int mAuthenticators;
     private boolean mDisallowBiometricsIfPolicyExists;
     private boolean mReceiveSystemEvents;
+    private int mSensorId = -1;
 
     public PromptInfo() {
 
@@ -59,6 +60,7 @@
         mAuthenticators = in.readInt();
         mDisallowBiometricsIfPolicyExists = in.readBoolean();
         mReceiveSystemEvents = in.readBoolean();
+        mSensorId = in.readInt();
     }
 
     public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() {
@@ -93,6 +95,7 @@
         dest.writeInt(mAuthenticators);
         dest.writeBoolean(mDisallowBiometricsIfPolicyExists);
         dest.writeBoolean(mReceiveSystemEvents);
+        dest.writeInt(mSensorId);
     }
 
     public boolean containsPrivateApiConfigurations() {
@@ -166,6 +169,10 @@
         mReceiveSystemEvents = receiveSystemEvents;
     }
 
+    public void setSensorId(int sensorId) {
+        mSensorId = sensorId;
+    }
+
     // Getters
 
     public CharSequence getTitle() {
@@ -226,4 +233,8 @@
     public boolean isReceiveSystemEvents() {
         return mReceiveSystemEvents;
     }
+
+    public int getSensorId() {
+        return mSensorId;
+    }
 }
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index d932865..66b9600 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -24,7 +24,6 @@
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.Manifest.permission.USE_FINGERPRINT;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresFeature;
@@ -56,8 +55,6 @@
 import android.util.Slog;
 import android.view.Surface;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.security.Signature;
 import java.util.ArrayList;
 import java.util.List;
@@ -98,13 +95,6 @@
      */
     public static final int SENSOR_ID_ANY = -1;
 
-    /**
-     * @hide
-     */
-    @IntDef({SENSOR_ID_ANY})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SensorId {}
-
     private IFingerprintService mService;
     private Context mContext;
     private IBinder mToken = new Binder();
@@ -508,8 +498,8 @@
      */
     @RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})
     public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
-            @NonNull AuthenticationCallback callback, Handler handler, @SensorId int sensorId,
-            int userId) {
+            @NonNull AuthenticationCallback callback, Handler handler, int sensorId, int userId) {
+
         if (callback == null) {
             throw new IllegalArgumentException("Must supply an authentication callback");
         }
@@ -653,15 +643,12 @@
      */
     @RequiresPermission(MANAGE_FINGERPRINT)
     public void generateChallenge(int userId, GenerateChallengeCallback callback) {
-        final List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties =
-                getSensorPropertiesInternal();
-        if (fingerprintSensorProperties.isEmpty()) {
+        final FingerprintSensorPropertiesInternal sensorProps = getFirstFingerprintSensor();
+        if (sensorProps == null) {
             Slog.e(TAG, "No sensors");
             return;
         }
-
-        final int sensorId = fingerprintSensorProperties.get(0).sensorId;
-        generateChallenge(sensorId, userId, callback);
+        generateChallenge(sensorProps.sensorId, userId, callback);
     }
 
     /**
@@ -681,18 +668,18 @@
      */
     @RequiresPermission(MANAGE_FINGERPRINT)
     public void revokeChallenge(int userId, long challenge) {
-        if (mService != null) try {
-            final List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties =
-                    getSensorPropertiesInternal();
-            if (fingerprintSensorProperties.isEmpty()) {
-                Slog.e(TAG, "No sensors");
-                return;
+        if (mService != null) {
+            try {
+                final FingerprintSensorPropertiesInternal sensorProps = getFirstFingerprintSensor();
+                if (sensorProps == null) {
+                    Slog.e(TAG, "No sensors");
+                    return;
+                }
+                mService.revokeChallenge(mToken, sensorProps.sensorId, userId,
+                        mContext.getOpPackageName(), challenge);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
-            final int sensorId = fingerprintSensorProperties.get(0).sensorId;
-            mService.revokeChallenge(mToken, sensorId, userId, mContext.getOpPackageName(),
-                    challenge);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -1161,6 +1148,12 @@
         }
     }
 
+    @Nullable
+    private FingerprintSensorPropertiesInternal getFirstFingerprintSensor() {
+        final List<FingerprintSensorPropertiesInternal> allSensors = getSensorPropertiesInternal();
+        return allSensors.isEmpty() ? null : allSensors.get(0);
+    }
+
     private void cancelEnrollment() {
         if (mService != null) try {
             mService.cancelEnrollment(mToken);
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index b39df4d..c69c47f 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -93,6 +93,10 @@
     int[] getVibratorIds(int deviceId);
     boolean isVibrating(int deviceId);
 
+    // Input device battery query.
+    int getBatteryStatus(int deviceId);
+    int getBatteryCapacity(int deviceId);
+
     void setPointerIconType(int typeId);
     void setCustomPointerIcon(in PointerIcon icon);
 
diff --git a/core/java/android/hardware/input/InputDeviceBattery.java b/core/java/android/hardware/input/InputDeviceBattery.java
new file mode 100644
index 0000000..0fe124e
--- /dev/null
+++ b/core/java/android/hardware/input/InputDeviceBattery.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.IInputConstants.INVALID_BATTERY_CAPACITY;
+
+import android.hardware.Battery;
+
+/**
+ * Battery implementation for input devices.
+ *
+ * @hide
+ */
+public final class InputDeviceBattery extends Battery {
+    private static final float NULL_BATTERY_CAPACITY = -1.0f;
+
+    private final InputManager mInputManager;
+    private final int mDeviceId;
+    private final boolean mHasBattery;
+
+    InputDeviceBattery(InputManager inputManager, int deviceId, boolean hasBattery) {
+        mInputManager = inputManager;
+        mDeviceId = deviceId;
+        mHasBattery = hasBattery;
+    }
+
+    @Override
+    public boolean hasBattery() {
+        return mHasBattery;
+    }
+
+    @Override
+    public int getStatus() {
+        if (!mHasBattery) {
+            return BATTERY_STATUS_UNKNOWN;
+        }
+        return mInputManager.getBatteryStatus(mDeviceId);
+    }
+
+    @Override
+    public float getCapacity() {
+        if (mHasBattery) {
+            int capacity = mInputManager.getBatteryCapacity(mDeviceId);
+            if (capacity != INVALID_BATTERY_CAPACITY) {
+                return (float) capacity / 100.0f;
+            }
+        }
+        return NULL_BATTERY_CAPACITY;
+    }
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 6ab1106..185c59d 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.app.ActivityThread;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -909,18 +910,17 @@
     }
 
     /**
-     * Returns the maximum allowed obscuring opacity by UID to propagate touches.
+     * Returns the maximum allowed obscuring opacity per UID to propagate touches.
      *
-     * For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams
-     * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows
-     * above the touch-consuming window.
+     * <p>For certain window types (eg. {@link LayoutParams#TYPE_APPLICATION_OVERLAY}), the decision
+     * of honoring {@link LayoutParams#FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring
+     * opacity of the windows above the touch-consuming window, per UID. Check documentation of
+     * {@link LayoutParams#FLAG_NOT_TOUCHABLE} for more details.
      *
-     * @see #setMaximumObscuringOpacityForTouch(Context, float)
-     *
-     * @hide
+     * @see LayoutParams#FLAG_NOT_TOUCHABLE
      */
-    @TestApi
-    public float getMaximumObscuringOpacityForTouch(@NonNull Context context) {
+    public float getMaximumObscuringOpacityForTouch() {
+        Context context = ActivityThread.currentApplication();
         return Settings.Global.getFloat(context.getContentResolver(),
                 Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
                 DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
@@ -946,17 +946,18 @@
      *
      * This value should be between 0 (inclusive) and 1 (inclusive).
      *
-     * @see #getMaximumObscuringOpacityForTouch(Context)
+     * @see #getMaximumObscuringOpacityForTouch()
      *
      * @hide
      */
     @TestApi
     @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void setMaximumObscuringOpacityForTouch(@NonNull Context context, float opacity) {
+    public void setMaximumObscuringOpacityForTouch(float opacity) {
         if (opacity < 0 || opacity > 1) {
             throw new IllegalArgumentException(
                     "Maximum obscuring opacity for touch should be >= 0 and <= 1");
         }
+        Context context = ActivityThread.currentApplication();
         Settings.Global.putFloat(context.getContentResolver(),
                 Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, opacity);
     }
@@ -1244,6 +1245,32 @@
     }
 
     /**
+     * Get the battery status of the input device
+     * @param deviceId The input device ID
+     * @hide
+     */
+    public int getBatteryStatus(int deviceId) {
+        try {
+            return mIm.getBatteryStatus(deviceId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the remaining battery capacity of the input device
+     * @param deviceId The input device ID
+     * @hide
+     */
+    public int getBatteryCapacity(int deviceId) {
+        try {
+            return mIm.getBatteryCapacity(deviceId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Add a runtime association between the input port and the display port. This overrides any
      * static associations.
      * @param inputPort The port of the input device.
@@ -1470,6 +1497,15 @@
     }
 
     /**
+     * Gets a battery object associated with an input device, assuming it has one.
+     * @return The battery, never null.
+     * @hide
+     */
+    public InputDeviceBattery getInputDeviceBattery(int deviceId, boolean hasBattery) {
+        return new InputDeviceBattery(this, deviceId, hasBattery);
+    }
+
+    /**
      * Listens for changes in input devices.
      */
     public interface InputDeviceListener {
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index 4224b7a..dfe748b 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -809,6 +809,9 @@
 permissions. It is unlikely that 3rd party apps will be able to use APIs protected by signature
 permissions as they are usually not signed with the platform certificate.
 
+If possible, [role protected permissions](#role-protected-permissions) should also be considered as
+an alternative to better restrict which apps may get the permission.
+
 Such permissions are defined and checked like an install time permission.
 
 ### Preinstalled permissions
@@ -819,6 +822,9 @@
 Hence this permission level is discouraged unless there are
 [further restrictions](#restricted-by-tests).
 
+If possible, [role protected permissions](#role-protected-permissions) should also be considered as
+an alternative to better restrict which apps may get the permission.
+
 Such permissions are defined and checked like an install time permission.
 
 ### Privileged permissions
@@ -833,6 +839,9 @@
 Hence this permission level is discouraged unless there are
 [further restrictions](#restricted-by-tests).
 
+If possible, [role protected permissions](#role-protected-permissions) should also be considered as
+an alternative to better restrict which apps may get the permission.
+
 Such permissions are defined and checked like an install time permission.
 
 #### Restricted by tests
@@ -890,8 +899,16 @@
 Which apps qualify for such a permission level is flexible and custom for each such level. Usually
 they refer to a single or small set of apps, usually - but not always - apps defined in AOSP.
 
+This type of permission is deprecated in favor of
+[role protected permissions](#role-protected-permissions).
+
 These permissions are defined and checked like an install time permission.
 
+### Role protected permissions
+
+See
+[Using role for permission protection](../../../../../../packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/role/RolePermissionProtection.md).
+
 ### Development permissions
 
 > Not recommended
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 79f055e..fbeb5de 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8055,6 +8055,15 @@
                 "one_handed_tutorial_show_count";
 
         /**
+         * Indicates whether transform is enabled.
+         * <p>
+         * Type: int (0 for false, 1 for true)
+         *
+         * @hide
+         */
+        public static final String TRANSFORM_ENABLED = "transform_enabled";
+
+        /**
          * The current night mode that has been selected by the user.  Owned
          * and controlled by UiModeManagerService.  Constants are as per
          * UiModeManager.
@@ -14721,9 +14730,8 @@
          *     touch, allow the UID to propagate the touch.
          * </ul>
          *
-         * @see android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch(Context)
-         * @see android.hardware.input.InputManager#setMaximumObscuringOpacityForTouch(Context,
-         * float)
+         * @see android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch()
+         * @see android.hardware.input.InputManager#setMaximumObscuringOpacityForTouch(float)
          *
          * @hide
          */
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index e0f3018..44daeff 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -46,7 +46,7 @@
     void onNotificationChannelGroupModification(String pkgName, in UserHandle user, in NotificationChannelGroup group, int modificationType);
 
     // assistants only
-    void onNotificationEnqueuedWithChannel(in IStatusBarNotificationHolder notificationHolder, in NotificationChannel channel);
+    void onNotificationEnqueuedWithChannel(in IStatusBarNotificationHolder notificationHolder, in NotificationChannel channel, in NotificationRankingUpdate update);
     void onNotificationSnoozedUntilContext(in IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId);
     void onNotificationsSeen(in List<String> keys);
     void onPanelRevealed(int items);
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index cf2152c..1d49a72 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -126,7 +126,7 @@
      * {@link #onNotificationEnqueued(StatusBarNotification, NotificationChannel)}.</p>
      *
      * @param sbn the new notification
-     * @return an adjustment or null to take no action, within 100ms.
+     * @return an adjustment or null to take no action, within 200ms.
      */
     abstract public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn);
 
@@ -135,7 +135,7 @@
      *
      * @param sbn the new notification
      * @param channel the channel the notification was posted to
-     * @return an adjustment or null to take no action, within 100ms.
+     * @return an adjustment or null to take no action, within 200ms.
      */
     public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn,
             @NonNull NotificationChannel channel) {
@@ -143,6 +143,20 @@
     }
 
     /**
+     * A notification was posted by an app. Called before post.
+     *
+     * @param sbn the new notification
+     * @param channel the channel the notification was posted to
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications.
+     * @return an adjustment or null to take no action, within 200ms.
+     */
+    public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn,
+            @NonNull NotificationChannel channel, @NonNull RankingMap rankingMap) {
+        return onNotificationEnqueued(sbn, channel);
+    }
+
+    /**
      * Implement this method to learn when notifications are removed, how they were interacted with
      * before removal, and why they were removed.
      * <p>
@@ -316,7 +330,7 @@
     private class NotificationAssistantServiceWrapper extends NotificationListenerWrapper {
         @Override
         public void onNotificationEnqueuedWithChannel(IStatusBarNotificationHolder sbnHolder,
-                NotificationChannel channel) {
+                NotificationChannel channel, NotificationRankingUpdate update) {
             StatusBarNotification sbn;
             try {
                 sbn = sbnHolder.get();
@@ -330,9 +344,11 @@
                 return;
             }
 
+            applyUpdateLocked(update);
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = sbn;
             args.arg2 = channel;
+            args.arg3 = getCurrentRanking();
             mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_ENQUEUED,
                     args).sendToTarget();
         }
@@ -472,8 +488,9 @@
                     SomeArgs args = (SomeArgs) msg.obj;
                     StatusBarNotification sbn = (StatusBarNotification) args.arg1;
                     NotificationChannel channel = (NotificationChannel) args.arg2;
+                    RankingMap ranking = (RankingMap) args.arg3;
                     args.recycle();
-                    Adjustment adjustment = onNotificationEnqueued(sbn, channel);
+                    Adjustment adjustment = onNotificationEnqueued(sbn, channel, ranking);
                     setAdjustmentIssuer(adjustment);
                     if (adjustment != null) {
                         if (!isBound()) {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index c41e599..64cddc3 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1431,7 +1431,8 @@
 
         @Override
         public void onNotificationEnqueuedWithChannel(
-                IStatusBarNotificationHolder notificationHolder, NotificationChannel channel)
+                IStatusBarNotificationHolder notificationHolder, NotificationChannel channel,
+                NotificationRankingUpdate update)
                 throws RemoteException {
             // no-op in the listener
         }
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index f4b90e1..bc03222 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -22,6 +22,7 @@
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.hardware.Battery;
 import android.hardware.SensorManager;
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.InputManager;
@@ -73,6 +74,7 @@
     private final boolean mHasMicrophone;
     private final boolean mHasButtonUnderPad;
     private final boolean mHasSensor;
+    private final boolean mHasBattery;
     private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
 
     @GuardedBy("mMotionRanges")
@@ -84,6 +86,9 @@
     @GuardedBy("mMotionRanges")
     private SensorManager mSensorManager;
 
+    @GuardedBy("mMotionRanges")
+    private Battery mBattery;
+
     /**
      * A mask for input source classes.
      *
@@ -323,6 +328,13 @@
     public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;
 
     /**
+     * The input source is a sensor associated with the input device.
+     *
+     * @see #SOURCE_CLASS_NONE
+     */
+    public static final int SOURCE_SENSOR = 0x04000000 | SOURCE_CLASS_NONE;
+
+    /**
      * A special input source constant that is used when filtering input devices
      * to match devices that provide any type of input source.
      */
@@ -448,7 +460,7 @@
     public InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
             int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
             KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone,
-            boolean hasButtonUnderPad, boolean hasSensor) {
+            boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery) {
         mId = id;
         mGeneration = generation;
         mControllerNumber = controllerNumber;
@@ -464,6 +476,7 @@
         mHasMicrophone = hasMicrophone;
         mHasButtonUnderPad = hasButtonUnderPad;
         mHasSensor = hasSensor;
+        mHasBattery = hasBattery;
         mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
     }
 
@@ -483,6 +496,7 @@
         mHasMicrophone = in.readInt() != 0;
         mHasButtonUnderPad = in.readInt() != 0;
         mHasSensor = in.readInt() != 0;
+        mHasBattery = in.readInt() != 0;
         mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);
 
         int numRanges = in.readInt();
@@ -830,6 +844,22 @@
     }
 
     /**
+     * Gets the battery object associated with the device, if there is one.
+     * Even if the device does not have a battery, the result is never null.
+     * Use {@link Battery#hasBattery} to determine whether a battery is
+     * present.
+     *
+     * @return The battery object associated with the device, never null.
+     */
+    @NonNull
+    public Battery getBattery() {
+        if (mBattery == null) {
+            mBattery = InputManager.getInstance().getInputDeviceBattery(mId, mHasBattery);
+        }
+        return mBattery;
+    }
+
+    /**
      * Gets the sensor manager service associated with the input device.
      * Even if the device does not have a sensor, the result is never null.
      * Use {@link SensorManager#getSensorList} to get a full list of all supported sensors.
@@ -1051,6 +1081,7 @@
         out.writeInt(mHasMicrophone ? 1 : 0);
         out.writeInt(mHasButtonUnderPad ? 1 : 0);
         out.writeInt(mHasSensor ? 1 : 0);
+        out.writeInt(mHasBattery ? 1 : 0);
 
         final int numRanges = mMotionRanges.size();
         out.writeInt(numRanges);
@@ -1097,6 +1128,8 @@
 
         description.append("  Has Sensor: ").append(mHasSensor).append("\n");
 
+        description.append("  Has battery: ").append(mHasBattery).append("\n");
+
         description.append("  Has mic: ").append(mHasMicrophone).append("\n");
 
         description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 7faa222..fa471fa 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1555,17 +1555,26 @@
          *   <li><b>Fully transparent windows</b>: This window has {@link LayoutParams#alpha} equal
          *   to 0.
          *   <li><b>One SAW window with enough transparency</b>: This window is of type {@link
-         *   #TYPE_APPLICATION_OVERLAY}, has {@link LayoutParams#alpha} below or equal to <b>0.8</b>
-         *   and it's the <b>only</b> window of type {@link #TYPE_APPLICATION_OVERLAY} from this UID
-         *   in the touch path.
+         *   #TYPE_APPLICATION_OVERLAY}, has {@link LayoutParams#alpha} below or equal to the
+         *   <a href="#MaximumOpacity">maximum obscuring opacity</a> (see below) and it's the
+         *   <b>only</b> window of type {@link #TYPE_APPLICATION_OVERLAY} from this UID in the touch
+         *   path.
          *   <li><b>Multiple SAW windows with enough transparency</b>: The multiple overlapping
          *   {@link #TYPE_APPLICATION_OVERLAY} windows in the
          *   touch path from this UID have a <b>combined obscuring opacity</b> below or equal to
-         *   <b>0.8</b>. See section below on how to compute this value.
+         *   the <a href="#MaximumOpacity">maximum obscuring opacity</a>. See section
+         *   <a href="#ObscuringOpacity">Combined obscuring opacity</a> below on how to compute this
+         *   value.
          * </ol>
          * <p>If none of these cases hold, the touch will not be delivered and a message will be
          * logged to logcat.</p>
          *
+         * <a name="MaximumOpacity"></a>
+         * <h3>Maximum obscuring opacity</h3>
+         * <p>This value is <b>0.8</b>. Apps that want to gather this value from the system rather
+         * than hard-coding it might want to use {@link
+         * android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch()}.</p>
+         *
          * <a name="ObscuringOpacity"></a>
          * <h3>Combined obscuring opacity</h3>
          *
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 13358daf..1f09489 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -62,6 +62,11 @@
      */
     public static final String ENABLE_NAS_FEEDBACK = "enable_nas_feedback";
 
+    /**
+     * Whether the Notification Assistant can label a notification not a conversation
+     */
+    public static final String ENABLE_NAS_NOT_CONVERSATION = "enable_nas_not_conversation";
+
     // Flags related to screenshot intelligence
 
     /**
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 4eaa016..9cc7243 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -70,7 +70,8 @@
                                           deviceInfo.isExternal(), deviceInfo.getSources(),
                                           deviceInfo.getKeyboardType(), kcmObj.get(),
                                           deviceInfo.hasVibrator(), hasMic,
-                                          deviceInfo.hasButtonUnderPad(), deviceInfo.hasSensor()));
+                                          deviceInfo.hasButtonUnderPad(), deviceInfo.hasSensor(),
+                                          deviceInfo.hasBattery()));
 
     const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
     for (const InputDeviceInfo::MotionRange& range: ranges) {
@@ -90,9 +91,10 @@
     gInputDeviceClassInfo.clazz = FindClassOrDie(env, "android/view/InputDevice");
     gInputDeviceClassInfo.clazz = MakeGlobalRefOrDie(env, gInputDeviceClassInfo.clazz);
 
-    gInputDeviceClassInfo.ctor = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
-                                                  "(IIILjava/lang/String;IILjava/lang/"
-                                                  "String;ZIILandroid/view/KeyCharacterMap;ZZZZ)V");
+    gInputDeviceClassInfo.ctor =
+            GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
+                             "(IIILjava/lang/String;IILjava/lang/"
+                             "String;ZIILandroid/view/KeyCharacterMap;ZZZZZ)V");
 
     gInputDeviceClassInfo.addMotionRange = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz,
             "addMotionRange", "(IIFFFFF)V");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 4ef63ae..522e142 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -27,6 +27,7 @@
 #include <android-base/chrono_utils.h>
 #include <android/graphics/region.h>
 #include <android/gui/BnScreenCaptureListener.h>
+#include <android/os/IInputConstants.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_hardware_HardwareBuffer.h>
 #include <android_runtime/android_view_Surface.h>
@@ -1619,7 +1620,8 @@
                                         jlong frameTimelineVsyncId) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
 
-    transaction->setFrameTimelineVsync(frameTimelineVsyncId);
+    transaction->setFrameTimelineInfo(
+            {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID});
 }
 
 class JankDataListenerWrapper : public JankDataListener {
diff --git a/core/res/res/values-es-rMX/donottranslate-cldr.xml b/core/res/res/values-es-rMX/donottranslate-cldr.xml
new file mode 100755
index 0000000..db438f2
--- /dev/null
+++ b/core/res/res/values-es-rMX/donottranslate-cldr.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_day_year">%-e %B %Y</string>
+    <string name="time_of_day">%H:%M:%S</string>
+    <string name="date_and_time">%-e %b %Y, %H:%M:%S</string>
+    <string name="date_time">%1$s, %2$s</string>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 98b36c5..f6d1b7d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1585,6 +1585,8 @@
 
     <!-- Template to be used to name enrolled fingerprints by default. -->
     <string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string>
+    <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their fingerprint. [CHAR LIMIT=70] -->
+    <string name="fingerprint_dialog_default_subtitle">Use your fingerprint to continue</string>
 
     <!-- Array containing custom error messages from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index dfccdf4..a60516a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2487,6 +2487,7 @@
   <java-symbol type="string" name="fingerprint_error_lockout" />
   <java-symbol type="string" name="fingerprint_error_lockout_permanent" />
   <java-symbol type="string" name="fingerprint_name_template" />
+  <java-symbol type="string" name="fingerprint_dialog_default_subtitle" />
   <java-symbol type="string" name="fingerprint_authenticated" />
   <java-symbol type="string" name="fingerprint_error_no_fingerprints" />
   <java-symbol type="string" name="fingerprint_error_hw_not_present" />
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 88faa0a..57c0be5 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -78,6 +78,7 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -334,7 +335,8 @@
     private ParsingPackage parsePackage(Uri packageURI) {
         final String archiveFilePath = packageURI.getPath();
         ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime(
-                new File(archiveFilePath), 0 /*flags*/, false /*collectCertificates*/);
+                new File(archiveFilePath), 0 /*flags*/, Collections.emptyList(),
+                false /*collectCertificates*/);
         if (result.isError()) {
             throw new IllegalStateException(result.getErrorMessage(), result.getException());
         }
diff --git a/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java b/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java
index b319886..341ee37 100644
--- a/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java
+++ b/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java
@@ -149,7 +149,7 @@
                 0 /* vendorId */, 0 /* productId */, "descriptor", true /* isExternal */,
                 0 /* sources */, 0 /* keyboardType */, null /* keyCharacterMap */,
                 false /* hasVibrator */, false /* hasMicrophone */, false /* hasButtonUnderpad */,
-                true /* hasSensor */);
+                true /* hasSensor */, false /* hasBattery */);
         assertTrue(d.hasSensor());
         return d;
     }
diff --git a/graphics/java/android/graphics/RenderEffect.java b/graphics/java/android/graphics/RenderEffect.java
index 496e470..ad4c3fe 100644
--- a/graphics/java/android/graphics/RenderEffect.java
+++ b/graphics/java/android/graphics/RenderEffect.java
@@ -190,7 +190,7 @@
     }
 
     /**
-     * Create a filter that applies the color filter to the provided RenderEffect
+     * Create a {@link RenderEffect} that applies the color filter to the provided RenderEffect
      *
      * @param colorFilter ColorFilter applied to the content in the input RenderEffect
      * @param renderEffect Source to be transformed by the specified {@link ColorFilter}
@@ -209,7 +209,7 @@
     }
 
     /**
-     * Create a filter that applies the color filter to the contents of the
+     * Create a {@link RenderEffect} that applies the color filter to the contents of the
      * {@link android.graphics.RenderNode} that this RenderEffect is installed on
      * @param colorFilter ColorFilter applied to the content in the input RenderEffect
      */
@@ -224,7 +224,7 @@
     }
 
     /**
-     * {@link RenderEffect} that is a composition of 2 other {@link RenderEffect} instances
+     * Create a {@link RenderEffect} that is a composition of 2 other {@link RenderEffect} instances
      * combined by the specified {@link BlendMode}
      *
      * @param dst The Dst pixels used in blending
@@ -248,8 +248,8 @@
     }
 
     /**
-     * Create a filter that composes 'inner' with 'outer', such that the results of 'inner' are
-     * treated as the source bitmap passed to 'outer', i.e.
+     * Create a {@link RenderEffect} that composes 'inner' with 'outer', such that the results of
+     * 'inner' are treated as the source bitmap passed to 'outer', i.e.
      *
      * <pre>
      * {@code
@@ -278,6 +278,18 @@
             );
     }
 
+    /**
+     * Create a {@link RenderEffect} that renders the contents of the input {@link Shader}.
+     * This is useful to create an input for other {@link RenderEffect} types such as
+     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, TileMode)}
+     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, TileMode)} or
+     * {@link RenderEffect#createColorFilterEffect(ColorFilter, RenderEffect)}.
+     */
+    @NonNull
+    public static RenderEffect createShaderEffect(@NonNull Shader shader) {
+        return new RenderEffect(nativeCreateShaderEffect(shader.getNativeInstance()));
+    }
+
     private final long mNativeRenderEffect;
 
     /* only constructed from static factory methods */
@@ -305,5 +317,6 @@
     private static native long nativeCreateColorFilterEffect(long colorFilter, long nativeInput);
     private static native long nativeCreateBlendModeEffect(long dst, long src, int blendmode);
     private static native long nativeCreateChainEffect(long outer, long inner);
+    private static native long nativeCreateShaderEffect(long shader);
     private static native long nativeGetFinalizer();
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index eaa704f..367f7e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -262,7 +262,6 @@
             final int yOffSet = Math.round(getDisplaySize().y * mOffSetFraction);
             mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
             mTimeoutHandler.resetTimer();
-
             mOneHandedUiEventLogger.writeEvent(
                     OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_IN);
         }
@@ -273,6 +272,9 @@
         if (mDisplayAreaOrganizer.isInOneHanded()) {
             mDisplayAreaOrganizer.scheduleOffset(0, 0);
             mTimeoutHandler.removeTimer();
+            //  Log metrics for Gesture navigation mode.
+            mOneHandedUiEventLogger.writeEvent(
+                    OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
         }
     }
 
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 615bf4d..58cbea6 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -615,6 +615,7 @@
         "tests/unit/CommonPoolTests.cpp",
         "tests/unit/DamageAccumulatorTests.cpp",
         "tests/unit/DeferredLayerUpdaterTests.cpp",
+        "tests/unit/EglManagerTests.cpp",
         "tests/unit/FatVectorTests.cpp",
         "tests/unit/GraphicsStatsServiceTests.cpp",
         "tests/unit/LayerUpdateQueueTests.cpp",
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 3aa5b4b..ca5f853 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -17,8 +17,10 @@
 #pragma once
 
 #include "pipeline/skia/SkiaDisplayList.h"
+#include "canvas/CanvasOpBuffer.h"
 
 #include <memory>
+#include <variant>
 
 namespace android {
 namespace uirenderer {
@@ -28,29 +30,25 @@
 };
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
-/**
- * Data structure that holds the list of commands used in display list stream
- */
-//using DisplayList = skiapipeline::SkiaDisplayList;
-class DisplayList {
+class SkiaDisplayListWrapper {
 public:
     // Constructs an empty (invalid) DisplayList
-    explicit DisplayList() {}
+    explicit SkiaDisplayListWrapper() {}
 
     // Constructs a DisplayList from a SkiaDisplayList
-    explicit DisplayList(std::unique_ptr<skiapipeline::SkiaDisplayList> impl)
+    explicit SkiaDisplayListWrapper(std::unique_ptr<skiapipeline::SkiaDisplayList> impl)
         : mImpl(std::move(impl)) {}
 
     // Move support
-    DisplayList(DisplayList&& other) : mImpl(std::move(other.mImpl)) {}
-    DisplayList& operator=(DisplayList&& other) {
+    SkiaDisplayListWrapper(SkiaDisplayListWrapper&& other) : mImpl(std::move(other.mImpl)) {}
+    SkiaDisplayListWrapper& operator=(SkiaDisplayListWrapper&& other) {
         mImpl = std::move(other.mImpl);
         return *this;
     }
 
     // No copy support
-    DisplayList(const DisplayList& other) = delete;
-    DisplayList& operator=(const DisplayList&) = delete;
+    SkiaDisplayListWrapper(const SkiaDisplayListWrapper& other) = delete;
+    SkiaDisplayListWrapper& operator=(const SkiaDisplayListWrapper&) = delete;
 
     void updateChildren(std::function<void(RenderNode*)> updateFn) {
         mImpl->updateChildren(std::move(updateFn));
@@ -137,7 +135,7 @@
 
     void applyColorTransform(ColorTransform transform) {
         if (mImpl) {
-            mImpl->mDisplayList.applyColorTransform(transform);
+            mImpl->applyColorTransform(transform);
         }
     }
 
@@ -145,5 +143,172 @@
     std::unique_ptr<skiapipeline::SkiaDisplayList> mImpl;
 };
 
+
+/**
+ * Data structure that holds the list of commands used in display list stream
+ */
+//using DisplayList = skiapipeline::SkiaDisplayList;
+class MultiDisplayList {
+private:
+    using SkiaDisplayList = skiapipeline::SkiaDisplayList;
+
+    struct EmptyList {
+        bool hasText() const { return false; }
+        void updateChildren(std::function<void(RenderNode*)> updateFn) {}
+        bool isEmpty() const { return true; }
+        bool containsProjectionReceiver() const { return false; }
+        bool hasVectorDrawables() const { return false; }
+        size_t getUsedSize() const { return 0; }
+        size_t getAllocatedSize() const { return 0; }
+        void output(std::ostream& output, uint32_t level) const { }
+        bool hasFunctor() const { return false; }
+        bool prepareListAndChildren(
+                TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
+                std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
+            return false;
+        }
+        void syncContents(const WebViewSyncData& data) { }
+        void applyColorTransform(ColorTransform transform) { }
+    };
+
+    std::variant<EmptyList, std::unique_ptr<SkiaDisplayList>, CanvasOpBuffer> mImpls;
+
+    template <typename T>
+    static constexpr T& get(T& t) { return t; }
+    template <typename T>
+    static constexpr const T& get(const T& t) { return t; }
+
+    template <typename T>
+    static constexpr T& get(std::unique_ptr<T>& t) { return *t; }
+    template <typename T>
+    static constexpr const T& get(const std::unique_ptr<T>& t) { return *t; }
+
+    template <typename T>
+    auto apply(T&& t) {
+        return std::visit([&t](auto& it) -> auto {
+            return t(get(it));
+        }, mImpls);
+    }
+
+    template <typename T>
+    auto apply(T&& t) const {
+        return std::visit([&t](const auto& it) -> auto {
+            return t(get(it));
+        }, mImpls);
+    }
+
+public:
+    // Constructs an empty (invalid) DisplayList
+    explicit MultiDisplayList() {}
+
+    // Constructs a DisplayList from a SkiaDisplayList
+    explicit MultiDisplayList(std::unique_ptr<SkiaDisplayList> impl)
+        : mImpls(std::move(impl)) {}
+
+    explicit MultiDisplayList(CanvasOpBuffer&& opBuffer) : mImpls(std::move(opBuffer)) {}
+
+    // Move support
+    MultiDisplayList(MultiDisplayList&& other) : mImpls(std::move(other.mImpls)) {}
+    MultiDisplayList& operator=(MultiDisplayList&& other) {
+        mImpls = std::move(other.mImpls);
+        return *this;
+    }
+
+    // No copy support
+    MultiDisplayList(const MultiDisplayList& other) = delete;
+    MultiDisplayList& operator=(const MultiDisplayList&) = delete;
+
+    void updateChildren(std::function<void(RenderNode*)> updateFn) {
+        apply([&](auto& it) { it.updateChildren(std::move(updateFn)); });
+    }
+
+    [[nodiscard]] explicit operator bool() const {
+        return isValid();
+    }
+
+    // If true this DisplayList contains a backing content, even if that content is empty
+    // If false, there this DisplayList is in an "empty" state
+    [[nodiscard]] bool isValid() const {
+        return mImpls.index() != 0;
+    }
+
+    [[nodiscard]] bool isEmpty() const {
+        return apply([](const auto& it) -> auto { return it.isEmpty(); });
+    }
+
+    [[nodiscard]] bool hasContent() const {
+        return !isEmpty();
+    }
+
+    [[nodiscard]] bool containsProjectionReceiver() const {
+        return apply([](const auto& it) -> auto { return it.containsProjectionReceiver(); });
+    }
+
+    [[nodiscard]] SkiaDisplayList* asSkiaDl() {
+        return std::get<1>(mImpls).get();
+    }
+
+    [[nodiscard]] const SkiaDisplayList* asSkiaDl() const {
+        return std::get<1>(mImpls).get();
+    }
+
+    [[nodiscard]] bool hasVectorDrawables() const {
+        return apply([](const auto& it) -> auto { return it.hasVectorDrawables(); });
+    }
+
+    void clear(RenderNode* owningNode = nullptr) {
+        if (owningNode && mImpls.index() == 1) {
+            auto& skiaDl = std::get<1>(mImpls);
+            if (skiaDl->reuseDisplayList(owningNode)) {
+                skiaDl.release();
+            }
+        }
+        mImpls = EmptyList{};
+    }
+
+    [[nodiscard]] size_t getUsedSize() const {
+        return apply([](const auto& it) -> auto { return it.getUsedSize(); });
+    }
+
+    [[nodiscard]] size_t getAllocatedSize() const {
+        return apply([](const auto& it) -> auto { return it.getAllocatedSize(); });
+    }
+
+    void output(std::ostream& output, uint32_t level) const {
+        apply([&](const auto& it) { it.output(output, level); });
+    }
+
+    [[nodiscard]] bool hasFunctor() const {
+        return apply([](const auto& it) -> auto { return it.hasFunctor(); });
+    }
+
+    bool prepareListAndChildren(
+            TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
+            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
+        return apply([&](auto& it) -> auto {
+            return it.prepareListAndChildren(observer, info, functorsNeedLayer, std::move(childFn));
+        });
+    }
+
+    void syncContents(const WebViewSyncData& data) {
+        apply([&](auto& it) { it.syncContents(data); });
+    }
+
+    [[nodiscard]] bool hasText() const {
+        return apply([](const auto& it) -> auto { return it.hasText(); });
+    }
+
+    void applyColorTransform(ColorTransform transform) {
+        apply([=](auto& it) { it.applyColorTransform(transform); });
+    }
+
+    [[nodiscard]] CanvasOpBuffer& asOpBuffer() {
+        return std::get<CanvasOpBuffer>(mImpls);
+    }
+};
+
+// For now stick to the original single-type container to avoid any regressions
+using DisplayList = SkiaDisplayListWrapper;
+
 }  // namespace uirenderer
 }  // namespace android
diff --git a/libs/hwui/canvas/CanvasFrontend.h b/libs/hwui/canvas/CanvasFrontend.h
index d749d2f..f9a6101 100644
--- a/libs/hwui/canvas/CanvasFrontend.h
+++ b/libs/hwui/canvas/CanvasFrontend.h
@@ -147,8 +147,7 @@
 public:
     template<class... Args>
     CanvasFrontend(int width, int height, Args&&... args) : CanvasStateHelper(width, height),
-            mReceiver(std::forward<Args>(args)...) { }
-    ~CanvasFrontend() = default;
+            mReceiver(std::in_place, std::forward<Args>(args)...) { }
 
     void save(SaveFlags::Flags flags = SaveFlags::MatrixClip) {
         if (internalSave(flagsToSaveEntry(flags))) {
@@ -186,7 +185,10 @@
         submit(std::move(op));
     }
 
-    const CanvasOpReceiver& receiver() const { return *mReceiver; }
+    const CanvasOpReceiver& receiver() const {
+        LOG_ALWAYS_FATAL_IF(!mReceiver.has_value());
+        return *mReceiver;
+    }
 
     CanvasOpReceiver finish() {
         auto ret = std::move(mReceiver.value());
@@ -205,6 +207,7 @@
 
     template <CanvasOpType T>
     void submit(CanvasOp<T>&& op) {
+        LOG_ALWAYS_FATAL_IF(!mReceiver.has_value());
         mReceiver->push_container(CanvasOpContainer(std::move(op), transform()));
     }
 };
diff --git a/libs/hwui/canvas/CanvasOpBuffer.cpp b/libs/hwui/canvas/CanvasOpBuffer.cpp
index 7054e47e..6089c572 100644
--- a/libs/hwui/canvas/CanvasOpBuffer.cpp
+++ b/libs/hwui/canvas/CanvasOpBuffer.cpp
@@ -22,4 +22,32 @@
 
 template class OpBuffer<CanvasOpType, CanvasOpContainer>;
 
+void CanvasOpBuffer::updateChildren(std::function<void(RenderNode*)> updateFn) {
+    // TODO: Do we need a fast-path for finding children?
+    if (mHas.children) {
+        for (auto& iter : filter<CanvasOpType::DrawRenderNode>()) {
+            updateFn(iter->renderNode.get());
+        }
+    }
+}
+
+void CanvasOpBuffer::output(std::ostream& output, uint32_t level) const {
+    LOG_ALWAYS_FATAL("TODO");
+}
+
+bool CanvasOpBuffer::prepareListAndChildren(
+            TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
+            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
+    LOG_ALWAYS_FATAL("TODO");
+    return false;
+}
+
+void CanvasOpBuffer::syncContents(const WebViewSyncData& data) {
+    LOG_ALWAYS_FATAL("TODO");
+}
+
+void CanvasOpBuffer::applyColorTransform(ColorTransform transform) {
+    LOG_ALWAYS_FATAL("TODO");
+}
+
 }  // namespace android::uirenderer
diff --git a/libs/hwui/canvas/CanvasOpBuffer.h b/libs/hwui/canvas/CanvasOpBuffer.h
index 07e079a..af797ca 100644
--- a/libs/hwui/canvas/CanvasOpBuffer.h
+++ b/libs/hwui/canvas/CanvasOpBuffer.h
@@ -19,10 +19,17 @@
 #include <SkMatrix.h>
 
 #include "CanvasOpTypes.h"
+#include "CanvasTransform.h"
 #include "OpBuffer.h"
+#include "TreeInfo.h"
+#include "private/hwui/WebViewFunctor.h"
+
+#include <functional>
 
 namespace android::uirenderer {
 
+class RenderNode;
+
 template <CanvasOpType T>
 struct CanvasOp;
 
@@ -53,12 +60,74 @@
 };
 
 extern template class OpBuffer<CanvasOpType, CanvasOpContainer>;
-class CanvasOpBuffer final : public OpBuffer<CanvasOpType, CanvasOpContainer> {
+class CanvasOpBuffer final : private OpBuffer<CanvasOpType, CanvasOpContainer> {
+private:
+    using SUPER = OpBuffer<CanvasOpType, CanvasOpContainer>;
+
 public:
+    // Expose select superclass methods publicly
+    using SUPER::for_each;
+    using SUPER::size;
+    using SUPER::resize;
+
     template <CanvasOpType T>
     void push(CanvasOp<T>&& op) {
         push_container(CanvasOpContainer<T>(std::move(op)));
     }
+
+    template <CanvasOpType T>
+    void push_container(CanvasOpContainer<T>&& op) {
+        if constexpr (IsDrawOp(T)) {
+            mHas.content = true;
+        }
+        if constexpr (T == CanvasOpType::DrawRenderNode) {
+            mHas.children = true;
+            // use staging property, since recording on UI thread
+            if (op->renderNode->stagingProperties().isProjectionReceiver()) {
+                mHas.projectionReceiver = true;
+            }
+        }
+        SUPER::push_container(std::move(op));
+    }
+
+    void clear() {
+        mHas = Contains{};
+        SUPER::clear();
+    }
+
+    void updateChildren(std::function<void(RenderNode*)> updateFn);
+    bool prepareListAndChildren(
+            TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
+            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn);
+    void syncContents(const WebViewSyncData& data);
+    void applyColorTransform(ColorTransform transform);
+
+    [[nodiscard]] bool isEmpty() const { return !mHas.content; }
+    [[nodiscard]] bool hasText() const { return mHas.text; }
+    [[nodiscard]] bool hasVectorDrawables() const { return mHas.vectorDrawable; }
+    [[nodiscard]] bool containsProjectionReceiver() const { return mHas.projectionReceiver; }
+    [[nodiscard]] bool hasFunctor() const { return mHas.functor; }
+
+    [[nodiscard]] size_t getUsedSize() const {
+        return size();
+    }
+
+    [[nodiscard]] size_t getAllocatedSize() const {
+        return capacity();
+    }
+
+    void output(std::ostream& output, uint32_t level) const;
+
+private:
+    struct Contains {
+        bool content : 1 = false;
+        bool children : 1 = false;
+        bool projectionReceiver : 1 = false;
+        bool text : 1 = false;
+        bool vectorDrawable : 1 = false;
+        bool functor : 1 = false;
+    };
+    Contains mHas;
 };
 
 }  // namespace android::uirenderer
diff --git a/libs/hwui/canvas/CanvasOpRasterizer.cpp b/libs/hwui/canvas/CanvasOpRasterizer.cpp
index 0093c38..9297604 100644
--- a/libs/hwui/canvas/CanvasOpRasterizer.cpp
+++ b/libs/hwui/canvas/CanvasOpRasterizer.cpp
@@ -33,21 +33,15 @@
     SkMatrix& currentGlobalTransform = globalMatrixStack.emplace_back(SkMatrix::I());
 
     source.for_each([&]<CanvasOpType T>(const CanvasOpContainer<T> * op) {
-        if constexpr (
-            T == CanvasOpType::BeginZ ||
-            T == CanvasOpType::EndZ   ||
-            T == CanvasOpType::DrawLayer
-        ) {
-            // Do beginZ or endZ
-            LOG_ALWAYS_FATAL("TODO");
-            return;
-        } else {
+        if constexpr (CanvasOpTraits::can_draw<CanvasOp<T>>) {
             // Generic OP
             // First apply the current transformation
             destination->setMatrix(SkMatrix::Concat(currentGlobalTransform, op->transform()));
             // Now draw it
             (*op)->draw(destination);
+            return;
         }
+        LOG_ALWAYS_FATAL("TODO, unable to rasterize %d", static_cast<int>(T));
     });
 }
 
diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h
index cde50bd..b55ef9d 100644
--- a/libs/hwui/canvas/CanvasOpTypes.h
+++ b/libs/hwui/canvas/CanvasOpTypes.h
@@ -35,7 +35,8 @@
     ClipPath,
 
     // Drawing ops
-    DrawColor,
+    DRAW_OP_BEGIN,
+    DrawColor = DRAW_OP_BEGIN,
     DrawRect,
     DrawRegion,
     DrawRoundRect,
@@ -59,10 +60,16 @@
     DrawImageLattice,
     DrawPicture,
     DrawLayer,
+    DrawRenderNode,
+    DRAW_OP_END = DrawRenderNode,
 
     // TODO: Rest
 
     COUNT  // must be last
 };
 
+static constexpr bool IsDrawOp(CanvasOpType t) {
+    return CanvasOpType::DRAW_OP_BEGIN <= t && t <= CanvasOpType::DRAW_OP_END;
+}
+
 }  // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index 86b1ac7..855cd0d 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -24,13 +24,15 @@
 #include <SkImage.h>
 #include <SkPicture.h>
 #include <SkRuntimeEffect.h>
-#include <hwui/Bitmap.h>
-#include <log/log.h>
-#include "CanvasProperty.h"
-#include "Points.h"
 
+#include <log/log.h>
+
+#include "hwui/Bitmap.h"
+#include "CanvasProperty.h"
 #include "CanvasOpTypes.h"
 #include "Layer.h"
+#include "Points.h"
+#include "RenderNode.h"
 
 #include <experimental/type_traits>
 #include <utility>
@@ -450,6 +452,11 @@
     sp<Layer> layer;
 };
 
+template<>
+struct CanvasOp<CanvasOpType::DrawRenderNode> {
+    sp<RenderNode> renderNode;
+};
+
 // cleanup our macros
 #undef ASSERT_DRAWABLE
 
diff --git a/libs/hwui/canvas/OpBuffer.h b/libs/hwui/canvas/OpBuffer.h
index 1237d69..8b5cdbb 100644
--- a/libs/hwui/canvas/OpBuffer.h
+++ b/libs/hwui/canvas/OpBuffer.h
@@ -64,7 +64,7 @@
     static constexpr auto STARTING_SIZE = PadAlign(sizeof(BufferHeader));
     using ItemHeader = OpBufferItemHeader<ItemTypes>;
 
-    OpBuffer() = default;
+    explicit OpBuffer() = default;
 
     // Prevent copying by default
     OpBuffer(const OpBuffer&) = delete;
@@ -135,7 +135,7 @@
 
     template <typename F>
     void for_each(F&& f) const {
-        for_each(std::forward<F>(f), ItemTypesSequence{});
+        do_for_each(std::forward<F>(f), ItemTypesSequence{});
     }
 
     void clear();
@@ -225,7 +225,7 @@
     }
 
     template <typename F, std::size_t... I>
-    void for_each(F&& f, std::index_sequence<I...>) const {
+    void do_for_each(F&& f, std::index_sequence<I...>) const {
         // Validate we're not empty
         if (isEmpty()) return;
 
diff --git a/libs/hwui/jni/RenderEffect.cpp b/libs/hwui/jni/RenderEffect.cpp
index 97c40d6..fa1752c 100644
--- a/libs/hwui/jni/RenderEffect.cpp
+++ b/libs/hwui/jni/RenderEffect.cpp
@@ -115,6 +115,18 @@
     return reinterpret_cast<jlong>(composeFilter.release());
 }
 
+static jlong createShaderEffect(
+    JNIEnv* env,
+    jobject,
+    jlong shaderHandle
+) {
+    auto* shader = reinterpret_cast<const SkShader*>(shaderHandle);
+    sk_sp<SkImageFilter> shaderFilter = SkImageFilters::Shader(
+          sk_ref_sp(shader), nullptr
+    );
+    return reinterpret_cast<jlong>(shaderFilter.release());
+}
+
 static void RenderEffect_safeUnref(SkImageFilter* filter) {
     SkSafeUnref(filter);
 }
@@ -130,7 +142,8 @@
     {"nativeCreateBitmapEffect", "(JFFFFFFFF)J", (void*)createBitmapEffect},
     {"nativeCreateColorFilterEffect", "(JJ)J", (void*)createColorFilterEffect},
     {"nativeCreateBlendModeEffect", "(JJI)J", (void*)createBlendModeEffect},
-    {"nativeCreateChainEffect", "(JJ)J", (void*)createChainEffect}
+    {"nativeCreateChainEffect", "(JJ)J", (void*)createChainEffect},
+    {"nativeCreateShaderEffect", "(J)J", (void*)createShaderEffect}
 };
 
 int register_android_graphics_RenderEffect(JNIEnv* env) {
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 483264f..1136e58 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <deque>
+
 #include "RecordingCanvas.h"
 #include "RenderNodeDrawable.h"
 #include "TreeInfo.h"
@@ -23,8 +25,6 @@
 #include "utils/LinearAllocator.h"
 #include "utils/Pair.h"
 
-#include <deque>
-
 namespace android {
 namespace uirenderer {
 
@@ -46,8 +46,10 @@
 
 class SkiaDisplayList {
 public:
-    size_t getUsedSize() { return allocator.usedSize() + mDisplayList.usedSize(); }
-    size_t getAllocatedSize() { return allocator.allocatedSize() + mDisplayList.allocatedSize(); }
+    size_t getUsedSize() const { return allocator.usedSize() + mDisplayList.usedSize(); }
+    size_t getAllocatedSize() const {
+        return allocator.allocatedSize() + mDisplayList.allocatedSize();
+    }
 
     ~SkiaDisplayList() {
         /* Given that we are using a LinearStdAllocator to store some of the
@@ -109,6 +111,10 @@
      */
     void syncContents(const WebViewSyncData& data);
 
+    void applyColorTransform(ColorTransform transform) {
+        mDisplayList.applyColorTransform(transform);
+    }
+
     /**
      * ONLY to be called by RenderNode::prepareTree in order to prepare this
      * list while the UI thread is blocked.  Here we can upload mutable bitmaps
@@ -154,12 +160,12 @@
     std::deque<RenderNodeDrawable> mChildNodes;
     std::deque<FunctorDrawable*> mChildFunctors;
     std::vector<SkImage*> mMutableImages;
+
 private:
     std::vector<Pair<VectorDrawableRoot*, SkMatrix>> mVectorDrawables;
+
 public:
-    void appendVD(VectorDrawableRoot* r) {
-        appendVD(r, SkMatrix::I());
-    }
+    void appendVD(VectorDrawableRoot* r) { appendVD(r, SkMatrix::I()); }
 
     void appendVD(VectorDrawableRoot* r, const SkMatrix& mat) {
         mVectorDrawables.push_back(Pair<VectorDrawableRoot*, SkMatrix>(r, mat));
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index eacabfd..633f21c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -490,9 +490,11 @@
 
     if (mNativeSurface) {
         // TODO(b/165985262): measure performance impact
-        if (const auto vsyncId = mCurrentFrameInfo->get(FrameInfoIndex::FrameTimelineVsyncId);
-                vsyncId != UiFrameInfoBuilder::INVALID_VSYNC_ID) {
-            native_window_set_frame_timeline_vsync(mNativeSurface->getNativeWindow(), vsyncId);
+        const auto vsyncId = mCurrentFrameInfo->get(FrameInfoIndex::FrameTimelineVsyncId);
+        if (vsyncId != UiFrameInfoBuilder::INVALID_VSYNC_ID) {
+            const auto inputEventId = mCurrentFrameInfo->get(FrameInfoIndex::NewestInputEvent);
+            native_window_set_frame_timeline_info(mNativeSurface->getNativeWindow(), vsyncId,
+                                                  inputEventId);
         }
     }
 
diff --git a/libs/hwui/tests/unit/CanvasFrontendTests.cpp b/libs/hwui/tests/unit/CanvasFrontendTests.cpp
index 05b1179..4ddcf6f 100644
--- a/libs/hwui/tests/unit/CanvasFrontendTests.cpp
+++ b/libs/hwui/tests/unit/CanvasFrontendTests.cpp
@@ -124,12 +124,12 @@
 
 TEST(CanvasFrontend, drawOpTransform) {
     CanvasFrontend<CanvasOpBuffer> opCanvas(100, 100);
-    const auto& receiver = opCanvas.receiver();
+    const auto &receiver = opCanvas.receiver();
 
     auto makeDrawRect = [] {
         return CanvasOp<CanvasOpType::DrawRect>{
-            .rect = SkRect::MakeWH(50, 50),
-            .paint = SkPaint(SkColors::kBlack),
+                .rect = SkRect::MakeWH(50, 50),
+                .paint = SkPaint(SkColors::kBlack),
         };
     };
 
@@ -167,14 +167,14 @@
 
     {
         // First result should be identity
-        const auto& result = transforms[0];
+        const auto &result = transforms[0];
         EXPECT_EQ(SkMatrix::kIdentity_Mask, result.getType());
         EXPECT_EQ(SkMatrix::I(), result);
     }
 
     {
         // Should be translate 10, 10
-        const auto& result = transforms[1];
+        const auto &result = transforms[1];
         EXPECT_EQ(SkMatrix::kTranslate_Mask, result.getType());
         SkMatrix m;
         m.setTranslate(10, 10);
@@ -183,7 +183,7 @@
 
     {
         // Should be translate 10, 10 + scale 2, 4
-        const auto& result = transforms[2];
+        const auto &result = transforms[2];
         EXPECT_EQ(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask, result.getType());
         SkMatrix m;
         m.setTranslate(10, 10);
@@ -193,7 +193,7 @@
 
     {
         // Should be translate 10, 10 + translate 20, 15
-        const auto& result = transforms[3];
+        const auto &result = transforms[3];
         EXPECT_EQ(SkMatrix::kTranslate_Mask, result.getType());
         SkMatrix m;
         m.setTranslate(30, 25);
@@ -202,9 +202,9 @@
 
     {
         // Should be translate 10, 10 + translate 20, 15 + rotate 90
-        const auto& result = transforms[4];
+        const auto &result = transforms[4];
         EXPECT_EQ(SkMatrix::kTranslate_Mask | SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask,
-                result.getType());
+                  result.getType());
         SkMatrix m;
         m.setTranslate(30, 25);
         m.preRotate(90.f);
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
index 54970df..a718d46 100644
--- a/libs/hwui/tests/unit/CanvasOpTests.cpp
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -149,7 +149,7 @@
     CanvasOpBuffer buffer;
     EXPECT_EQ(buffer.size(), 0);
     size_t numPts = 3;
-    auto pts = sk_ref_sp(
+    auto pts = sk_sp<Points>(
           new Points({
               {32, 16},
               {48, 48},
@@ -192,7 +192,7 @@
     CanvasOpBuffer buffer;
     EXPECT_EQ(buffer.size(), 0);
     size_t numPts = 3;
-    auto pts = sk_ref_sp(
+    auto pts = sk_sp<Points>(
         new Points({
                {32, 16},
                {48, 48},
diff --git a/libs/hwui/tests/unit/EglManagerTests.cpp b/libs/hwui/tests/unit/EglManagerTests.cpp
new file mode 100644
index 0000000..f7f2406
--- /dev/null
+++ b/libs/hwui/tests/unit/EglManagerTests.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "renderthread/EglManager.h"
+#include "tests/common/TestContext.h"
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::test;
+
+TEST(EglManager, doesSurfaceLeak) {
+    EglManager eglManager;
+    eglManager.initialize();
+
+    ASSERT_TRUE(eglManager.hasEglContext());
+
+    auto colorSpace = SkColorSpace::MakeSRGB();
+    for (int i = 0; i < 100; i++) {
+        TestContext context;
+        auto result =
+                eglManager.createSurface(context.surface().get(), ColorMode::Default, colorSpace);
+        EXPECT_TRUE(result);
+        EGLSurface surface = result.unwrap();
+        eglManager.destroySurface(surface);
+    }
+
+    eglManager.destroy();
+}
\ No newline at end of file
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index 6dd57b1..8c999c4 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -404,6 +404,7 @@
     EXPECT_TRUE(pipeline->isSurfaceReady());
     renderThread.destroyRenderingContext();
     EXPECT_FALSE(pipeline->isSurfaceReady());
+    LOG_ALWAYS_FATAL_IF(pipeline->isSurfaceReady());
 }
 
 RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, pictureCallback) {
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index bcc846b..bb1dbd4 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -739,6 +739,13 @@
             if (mBundle != null) {
                 aa.mBundle = new Bundle(mBundle);
             }
+
+            // Allow the FLAG_HW_HOTWORD only for AudioSource.VOICE_RECOGNITION
+            if (mSource != MediaRecorder.AudioSource.VOICE_RECOGNITION
+                    && (mFlags & FLAG_HW_HOTWORD) == FLAG_HW_HOTWORD) {
+                aa.mFlags &= ~FLAG_HW_HOTWORD;
+            }
+
             return aa;
         }
 
@@ -852,6 +859,23 @@
         }
 
         /**
+         * @hide
+         * Request for capture in hotword mode.
+         *
+         * Requests an audio path optimized for Hotword detection use cases from
+         * the low power audio DSP. This is valid only for capture with
+         * audio source {@link MediaRecorder.AudioSource#VOICE_RECOGNITION}.
+         * There is no guarantee that this mode is available on the device.
+         * @return the same Builder instance.
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
+        public @NonNull Builder setHotwordMode() {
+            mFlags |= FLAG_HW_HOTWORD;
+            return this;
+        }
+
+        /**
          * Specifies whether the audio may or may not be captured by other apps or the system.
          *
          * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index d40de76..205c1f4 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -354,7 +354,7 @@
 
     /**
      * @hide
-     * @return the internal device tyoe
+     * @return the internal device type
      */
     public int getInternalType() {
         return mPort.type();
diff --git a/media/java/android/media/AudioProfile.java b/media/java/android/media/AudioProfile.java
index 3cd615b..9774e80 100644
--- a/media/java/android/media/AudioProfile.java
+++ b/media/java/android/media/AudioProfile.java
@@ -18,6 +18,9 @@
 
 import android.annotation.NonNull;
 
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
 /**
  * An AudioProfile is specific to an audio format and lists supported sampling rates and
  * channel masks for that format.  An {@link AudioDeviceInfo} has a list of supported AudioProfiles.
@@ -63,4 +66,29 @@
     public @NonNull int[] getSampleRates() {
         return mSamplingRates;
     }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("{");
+        sb.append(AudioFormat.toLogFriendlyEncoding(mFormat));
+        if (mSamplingRates != null && mSamplingRates.length > 0) {
+            sb.append(", sampling rates=").append(Arrays.toString(mSamplingRates));
+        }
+        if (mChannelMasks != null && mChannelMasks.length > 0) {
+            sb.append(", channel masks=").append(toHexString(mChannelMasks));
+        }
+        if (mChannelIndexMasks != null && mChannelIndexMasks.length > 0) {
+            sb.append(", channel index masks=").append(Arrays.toString(mChannelIndexMasks));
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private static String toHexString(int[] ints) {
+        if (ints == null || ints.length == 0) {
+            return "";
+        }
+        return Arrays.stream(ints).mapToObj(anInt -> String.format("0x%02X, ", anInt))
+                .collect(Collectors.joining());
+    }
 }
diff --git a/media/java/android/media/MediaServiceManager.java b/media/java/android/media/MediaServiceManager.java
index 96bff4f..b899559 100644
--- a/media/java/android/media/MediaServiceManager.java
+++ b/media/java/android/media/MediaServiceManager.java
@@ -33,6 +33,7 @@
 public class MediaServiceManager {
     private static final String MEDIA_SESSION_SERVICE = "media_session";
     private static final String MEDIA_TRANSCODING_SERVICE = "media.transcoding";
+    private static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
 
     /**
      * @hide
@@ -79,4 +80,12 @@
     public ServiceRegisterer getMediaTranscodingServiceRegisterer() {
         return new ServiceRegisterer(MEDIA_TRANSCODING_SERVICE);
     }
+
+    /**
+     * Returns {@link ServiceRegisterer} for MEDIA_COMMUNICATION_SERVICE.
+     */
+    @NonNull
+    public ServiceRegisterer getMediaCommunicationServiceRegisterer() {
+        return new ServiceRegisterer(MEDIA_COMMUNICATION_SERVICE);
+    }
 }
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 6b329f8..b1baf94 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -23,6 +23,8 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -39,6 +41,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
+import android.util.Xml;
 import android.view.InputEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -99,6 +102,7 @@
     private int mSurfaceWidth;
     private int mSurfaceHeight;
     private final AttributeSet mAttrs;
+    private final XmlResourceParser mParser;
     private final int mDefStyleAttr;
     private int mWindowZOrder;
     private boolean mUseRequestedSurfaceLayout;
@@ -168,7 +172,16 @@
 
     public TvView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mAttrs = attrs;
+        int sourceResId = Resources.getAttributeSetSourceResId(attrs);
+        if (sourceResId != Resources.ID_NULL) {
+            Log.d(TAG, "Build local AttributeSet");
+            mParser  = context.getResources().getXml(sourceResId);
+            mAttrs = Xml.asAttributeSet(mParser);
+        } else {
+            Log.d(TAG, "Use passed in AttributeSet");
+            mParser = null;
+            mAttrs = attrs;
+        }
         mDefStyleAttr = defStyleAttr;
         resetSurfaceView();
         mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE);
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 620c7ae..72589e3 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -18,6 +18,7 @@
 
 import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
 import static android.text.TextUtils.emptyIfNull;
+import static android.text.TextUtils.isEmpty;
 import static android.text.TextUtils.withoutPrefix;
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
@@ -67,7 +68,13 @@
         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
         String deviceProfile = getRequest().getDeviceProfile();
-        String profileName = getDeviceProfileName(deviceProfile);
+        String profilePrivacyDisclaimer = emptyIfNull(getRequest()
+                .getDeviceProfilePrivilegesDescription())
+                .replace("APP_NAME", getCallingAppName());
+        boolean useDeviceProfile = deviceProfile != null && !isEmpty(profilePrivacyDisclaimer);
+        String profileName = useDeviceProfile
+                ? getDeviceProfileName(deviceProfile)
+                : getString(R.string.profile_name_generic);
 
         if (getRequest().isSingleDevice()) {
             setContentView(R.layout.device_confirmation);
@@ -110,15 +117,12 @@
 
         TextView profileSummary = findViewById(R.id.profile_summary);
 
-        if (deviceProfile != null) {
-            String privacyDisclaimer = emptyIfNull(getRequest()
-                    .getDeviceProfilePrivilegesDescription())
-                    .replace("APP_NAME", getCallingAppName());
+        if (useDeviceProfile) {
             profileSummary.setVisibility(View.VISIBLE);
             profileSummary.setText(getString(R.string.profile_summary,
                     getCallingAppName(),
                     profileName,
-                    privacyDisclaimer));
+                    profilePrivacyDisclaimer));
         } else {
             profileSummary.setVisibility(View.GONE);
         }
@@ -142,7 +146,7 @@
                 return getString(R.string.profile_name_watch);
             }
             default: {
-                Log.wtf(LOG_TAG,
+                Log.w(LOG_TAG,
                         "No localized profile name found for device profile: " + deviceProfile);
                 return withoutPrefix("android.app.role.COMPANION_DEVICE_", deviceProfile)
                         .toLowerCase()
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index fd71670..606cd57 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -322,7 +322,8 @@
 
     void onDeviceSelected(String callingPackage, String deviceAddress) {
         mServiceCallback.complete(new Association(
-                getUserId(), deviceAddress, callingPackage, mRequest.getDeviceProfile(), false));
+                getUserId(), deviceAddress, callingPackage, mRequest.getDeviceProfile(), false,
+                System.currentTimeMillis()));
     }
 
     void onCancel() {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 6f4f72a..3837743 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Sal nie outomaties koppel nie"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Geen internettoegang nie"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gestoor deur <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Outomaties deur %1$s gekoppel"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Outomaties deur netwerkgraderingverskaffer gekoppel"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Gekoppel via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 3f5df34..4ce01d6 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"በራስ-ሰር አይገናኝም"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ምንም የበይነመረብ መዳረሻ ያለም"</string>
     <string name="saved_network" msgid="7143698034077223645">"የተቀመጠው በ<xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"በ%1$s በኩል በራስ-ሰር ተገናኝቷል"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"በአውታረ መረብ ደረጃ ሰጪ አቅራቢ በኩል በራስ-ሰር ተገናኝቷል"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"በ%1$s በኩል መገናኘት"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 0351d94..2580d0f 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"لن يتم الاتصال تلقائيًا"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"لا يتوفّر اتصال بالإنترنت"</string>
     <string name="saved_network" msgid="7143698034077223645">"تم الحفظ بواسطة <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏تم الاتصال تلقائيًا عبر %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"تم الاتصال تلقائيًا عبر مقدم خدمة تقييم الشبكة"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"‏تم الاتصال عبر %1$s"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 0f7db8f..b61ff50 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"স্বয়ংক্ৰিয়ভাৱে সংযোগ নহ’ব"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g>এ ছেভ কৰিছে"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s মাধ্যমেদি স্বয়ংক্ৰিয়ভাৱে সংযোগ কৰা হৈছে"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"নেটৱৰ্ক ৰেটিং প্ৰদানকাৰীৰ জৰিয়তে স্বয়ং সংয়োগ কৰা হ’ল"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s-ৰ মাধ্যমেদি সংযোগ কৰা হৈছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 0855d17e..d063776 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Avtomatik qoşulmayacaq"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"İnternet girişi yoxdur"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> tərəfindən saxlandı"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s üzərindən avtomatik qoşuldu"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Avtomatik olaraq şəbəkə reytinq provayderi ilə qoşuludur"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s vasitəsilə qoşuludur"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 3386fe86..2976bb5 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automatsko povezivanje nije uspelo"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano preko %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano preko dobavljača ocene mreže"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 6ac2172..7af9e93 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Не будзе аўтаматычна падключацца"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Няма доступу да інтэрнэту"</string>
     <string name="saved_network" msgid="7143698034077223645">"Захавана праз: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аўтаматычна падключана праз %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аўтаматычна падключана праз пастаўшчыка паслугі ацэнкі сеткі"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Падключана праз %1$s"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 19ed5bd..77b6493 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Няма да се свърже автоматично"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Няма достъп до интернет"</string>
     <string name="saved_network" msgid="7143698034077223645">"Запазено от <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматично е установена връзка чрез %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматично е установена връзка чрез доставчик на услуги за оценяване на мрежите"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Установена е връзка през „%1$s“"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index b0e9342..819625b 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"অটোমেটিক কানেক্ট করবে না"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ইন্টারনেট অ্যাক্সেস নেই"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> দ্বারা সেভ করা"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"স্বয়ংক্রিয়ভাবে %1$s এর মাধ্যমে কানেক্ট হয়েছে"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"নেটওয়ার্কের রেটিং প্রদানকারীর মাধ্যমে অটোমেটিক কানেক্ট"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s মাধ্যমে কানেক্ট হয়েছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 9377624..193ac60 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Neće se automatski povezati"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Sačuvano: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano koristeći %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano putem ocjenjivača mreže"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Povezani preko %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index a2a7770..fef9bfb 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"No es connectarà automàticament"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No hi ha accés a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Desada per <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Connectada automàticament a través de: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Connectada automàticament a través d\'un proveïdor de valoració de xarxes"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connectada mitjançant %1$s"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 4db4d5c..281a788 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Připojení nebude automaticky navázáno"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nebyl zjištěn žádný přístup k internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Uloženo uživatelem <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaticky připojeno přes poskytovatele %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automaticky připojeno přes poskytovatele hodnocení sítí"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Připojeno prostřednictvím %1$s"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index b76afa5c..69cc8d8 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Der oprettes ikke automatisk forbindelse"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ingen internetadgang"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gemt af <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisk tilsluttet via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisk forbundet via udbyder af netværksvurdering"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Tilsluttet via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index ba760dd..737ea16 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Kein automatischer Verbindungsaufbau"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Kein Internetzugriff"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gespeichert von <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisch über %1$s verbunden"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisch über Anbieter von Netzwerkbewertungen verbunden"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Über %1$s verbunden"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index c608a62..8e1d5e3 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Δεν θα συνδεθεί αυτόματα"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Δεν υπάρχει πρόσβαση στο διαδίκτυο"</string>
     <string name="saved_network" msgid="7143698034077223645">"Αποθηκεύτηκε από <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Συνδέθηκε αυτόματα μέσω %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Συνδέθηκε αυτόματα μέσω παρόχου αξιολόγησης δικτύου"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Συνδέθηκε μέσω %1$s"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index e67c3d1..b98c4b8 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index b0830fc..aa0d3f1 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index e67c3d1..b98c4b8 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index e67c3d1..b98c4b8 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Won\'t automatically connect"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No Internet access"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Connected to metered network"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatically connected via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatically connected via network rating provider"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connected via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 4c0af75..c01f3a0 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎Won\'t automatically connect‎‏‎‎‏‎"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎No internet access‎‏‎‎‏‎"</string>
     <string name="saved_network" msgid="7143698034077223645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎Saved by ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎Connected to metered network‎‏‎‎‏‎"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎Automatically connected via %1$s‎‏‎‎‏‎"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎Automatically connected via network rating provider‎‏‎‎‏‎"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎Connected via %1$s‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 9ae7781..f79072f 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"No se conectará automáticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No hay acceso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conexión automática mediante %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automáticamente mediante proveedor de calificación de red"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Conexión a través de %1$s"</string>
@@ -116,8 +118,8 @@
     <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SINCRONIZAR"</string>
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"La sincronización te permite acceder a los contactos y al historial de llamadas cuando el dispositivo está conectado."</string>
-    <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"No se pudo sincronizar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se pudo sincronizar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> debido a que el PIN o la clave de acceso son incorrectos."</string>
+    <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> debido a que el PIN o la clave de acceso son incorrectos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"No se puede establecer la comunicación con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Vínculo rechazado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computadora"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 203726a..f99a3f1 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"No se establecerá conexión automáticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"No se ha detectado ningún acceso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectada automáticamente a través de %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automáticamente a través de un proveedor de valoración de redes"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado a través de %1$s"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 379ed6c..fa2aa46 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automaatselt ei ühendata"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Juurdepääs Internetile puudub"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salvestas: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ühendus loodi automaatselt teenusega %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ühendus loodi automaatselt võrgukvaliteedi hinnangute pakkuja kaudu"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Ühendatud üksuse %1$s kaudu"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 2582854..2c4a8ee 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Ez da konektatuko automatikoki"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ezin da konektatu Internetera"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s bidez automatikoki konektatuta"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikoki konektatuta sare-balorazioen hornitzailearen bidez"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s bidez konektatuta"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index cb598e5..1c6ca76 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"اتصال به‌صورت خودکار انجام نمی‌شود"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"دسترسی به اینترنت ندارد"</string>
     <string name="saved_network" msgid="7143698034077223645">"ذخیره‌شده توسط <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏اتصال خودکار ازطریق %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"اتصال خودکار ازطریق ارائه‌دهنده رتبه‌بندی شبکه"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"‏متصل از طریق %1$s"</string>
@@ -263,8 +265,8 @@
     <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"‏انتخاب نسخه MAP بلوتوث"</string>
     <string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"کدک بلوتوث صوتی"</string>
     <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"راه‌اندازی کدک صوتی بلوتوثی\nانتخاب"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"سرعت نمونه بلوتوث صوتی"</string>
-    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"راه‌اندازی کدک صوتی بلوتوثی\nانتخاب: سرعت نمونه"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"بسامد نمونه صوتی بلوتوث"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"راه‌اندازی کدک صوتی بلوتوثی\nانتخاب: بسامد نمونه"</string>
     <string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"«خاکستری» به این معناست که تلفن یا هدست از آن پشتیبانی نمی‌کند"</string>
     <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"بیت‌های بلوتوث صوتی در هر نمونه"</string>
     <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"راه‌اندازی کدک صوتی بلوتوثی\nانتخاب: تعداد بیت در نمونه"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 31dfe18..04c9130 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Yhteyttä ei muodosteta automaattisesti"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ei internetyhteyttä"</string>
     <string name="saved_network" msgid="7143698034077223645">"Tallentaja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaattinen yhteys muodostettu palvelun %1$s kautta"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Yhdistetty automaattisesti verkon arviointipalvelun kautta"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Yhdistetty seuraavan kautta: %1$s"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index a8476dd..aa0cd2a 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Aucun accès à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Enregistrés par <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatiquement connecté par %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Connecté automatiquement par le fournisseur d\'avis sur le réseau"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connecté par %1$s"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index a79ed0c..dbdc160 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Aucun accès à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Enregistré lors de : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Connecté automatiquement via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Connecté automatiquement via un fournisseur d\'évaluation de l\'état du réseau"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Connecté via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 97662a6..90c1303 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Non se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sen acceso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Gardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectouse automaticamente a través de %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectada automaticamente a través dun provedor de valoración de redes"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado a través de %1$s"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 46bd71b..4caeda2 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ઑટોમૅટિક રીતે કનેક્ટ કરશે નહીં"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા સચવાયું"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા ઑટોમૅટિક રીતે કનેક્ટ થયું"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 9cae311..468808b 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"अपने आप कनेक्ट नहीं होगा"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"इंटरनेट नहीं है"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्क रेटिंग कंपनी के ज़रिए अपने आप कनेक्ट है"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s के द्वारा उपलब्ध"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 83bb2d1..932c256 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Neće se povezati automatski"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Spremila aplik. <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezan putem %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezan putem ocjenjivača mreže"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Povezano putem %1$s"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 9f184c7..fbaffac 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nem csatlakozik automatikusan"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nincs internet-hozzáférés"</string>
     <string name="saved_network" msgid="7143698034077223645">"Mentette: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatikusan csatlakozott a következőn keresztül: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikusan csatlakozott a hálózatértékelés szolgáltatóján keresztül"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Csatlakozva a következőn keresztül: %1$s"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index cd6cbf3..224d641 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Չի միանա ավտոմատ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ինտերնետ կապ չկա"</string>
     <string name="saved_network" msgid="7143698034077223645">"Ով է պահել՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ավտոմատ միացել է ցանցերի վարկանիշի մատակարարի միջոցով"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Միացված է %1$s-ի միջոցով"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 3b80918..8cf13cd 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Tidak akan tersambung otomatis"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Tidak ada akses internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Disimpan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Tersambung otomatis melalui %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Otomatis tersambung melalui penyedia rating jaringan"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Terhubung melalui %1$s"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index ce9e665..aa8893e 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Mun ekki tengjast sjálfkrafa"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Enginn netaðgangur"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> vistaði"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Sjálfkrafa tengt um %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Sjálfkrafa tengt um netgæðaveitu"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Tengt í gegnum %1$s"</string>
@@ -226,12 +228,12 @@
     <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi-Fi pörunarkóði"</string>
     <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Pörun mistókst"</string>
     <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Gakktu úr skugga um að tækið sé tengt sama neti."</string>
-    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Tengja tæki með Wi-Fi með því að skanna QR-kóða"</string>
+    <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Para tæki gegnum Wi-Fi með því að skanna QR-kóða"</string>
     <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Parar tæki…"</string>
     <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Ekki tókst að para við tækið. Annað hvort var QR-kóðinn rangur eða tækið ekki tengt sama neti."</string>
     <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-tala og gátt"</string>
     <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skanna QR-kóða"</string>
-    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Tengja tæki með Wi-Fi með því að skanna QR-kóða"</string>
+    <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Para tæki gegnum Wi-Fi með því að skanna QR-kóða"</string>
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Tengstu Wi-Fi neti"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, villuleit, dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Flýtileið í villutilkynningu"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 93b24a0..0199f54 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Non verrà eseguita la connessione automatica"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nessun accesso a Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salvata da <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Collegato automaticamente tramite %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Collegato automaticamente tramite fornitore di servizi di valutazione rete"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Collegato tramite %1$s"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index ab67809..a50a22d 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"לא יתבצע חיבור באופן אוטומטי"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"אין גישה לאינטרנט"</string>
     <string name="saved_network" msgid="7143698034077223645">"נשמר על ידי <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏מחובר אוטומטית דרך %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"מחובר אוטומטית דרך ספק של דירוג רשת"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"‏מחובר דרך %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 711a22f..a1d1b70 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"自動的に接続されません"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"インターネット接続なし"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g>で保存"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s 経由で自動的に接続しています"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ネットワーク評価プロバイダ経由で自動的に接続しています"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s経由で接続"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 0813305..77fd4b1 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ავტომატურად დაკავშირება ვერ მოხერხდება"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="saved_network" msgid="7143698034077223645">"შენახული <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"ავტომატურად დაკავშირდა %1$s-ის მეშვეობით"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ავტომატურად დაკავშირდა ქსელის ხარისხის შეფასების პროვაიდერის მეშვეობით"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s-ით დაკავშირებული"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 16ee9c0..eb5cd54 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматты қосылмайды"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернетпен байланыс жоқ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> сақтаған"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s арқылы автоматты қосылды"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Желі рейтингі провайдері арқылы автоматты түрде қосылған"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s арқылы қосылған"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 5b47381..38abb80 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"នឹងមិនភ្ជាប់ដោយស្វ័យប្រវត្តិទេ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"មិនមាន​ការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
     <string name="saved_network" msgid="7143698034077223645">"បានរក្សាទុកដោយ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"បានភ្ជាប់ដោយស្វ័យប្រវត្តិតាមរយៈ %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"បានភ្ជាប់​ដោយស្វ័យប្រវត្តិ​តាម​រយៈក្រុមហ៊ុនផ្តល់​ការ​វាយ​តម្លៃលើ​បណ្តាញ"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"បានភ្ជាប់តាមរយៈ %1$s"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index fd63dcb..560fba15 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವಿಲ್ಲ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ನಿಂದ ಉಳಿಸಲಾಗಿದೆ"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ನೆಟ್‌ವರ್ಕ್ ರೇಟಿಂಗ್ ಒದಗಿಸುವವರ ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index a9c3f31..f43ce16 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"자동으로 연결되지 않습니다."</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"인터넷에 연결되어 있지 않음"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 저장됨"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s을(를) 통해 자동으로 연결됨"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"네트워크 평가 제공업체를 통해 자동으로 연결됨"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s을(를) 통해 연결됨"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index bc3656f..35b1ecac 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматтык түрдө туташпайт"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернетке туташпай турат"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s аркылуу автоматтык түрдө туташты"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Тармактар рейтингинин булагы аркылуу автоматтык түрдө туташты"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s аркылуу жеткиликтүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 8408c93..f60fe7f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ຈະບໍ່ເຊື່ອມຕໍ່ອັດຕະໂນມັດ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
     <string name="saved_network" msgid="7143698034077223645">"ບັນທຶກ​​​ໂດຍ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"ເຊື່ອມຕໍ່ຜ່ານທາງ %1$s ໂດຍອັດຕະໂນມັດ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ເຊື່ອມຕໍ່ກັບອັດຕະໂນມັດແລ້ວຜ່ານຜູ້ໃຫ້ບໍລິການຄະແນນເຄືອຂ່າຍ"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"​ເຊື່ອມຕໍ່​ຜ່ານ %1$s ​ແລ້ວ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 1dcfcf7..e66e3c5 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nebus automatiškai prisijungiama"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nėra interneto ryšio"</string>
     <string name="saved_network" msgid="7143698034077223645">"Išsaugojo <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatiškai prisijungta naudojant „%1$s“"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatiškai prisijungta naudojant tinklo įvertinimo paslaugos teikėjo paslaugomis"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Prisijungta naudojant „%1$s“"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 3d9b78a..a8bd2cc 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Savienojums netiks izveidots automātiski"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nav piekļuves internetam"</string>
     <string name="saved_network" msgid="7143698034077223645">"Saglabāja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Izveidots savienojums ar maksas tīklu"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automātiski savienots, izmantojot %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automātiski izveidots savienojums, izmantojot tīkla vērtējuma sniedzēju"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Savienots, izmantojot %1$s"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 0674f11..90bcc04 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Не може да се поврзе автоматски"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Нема пристап до интернет"</string>
     <string name="saved_network" msgid="7143698034077223645">"Зачувано од <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматски поврзано преку %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматски поврзано преку оценувач на мрежа"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Поврзано преку %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 1455669..ba1987b 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"സ്വയമേവ കണക്‌റ്റുചെയ്യില്ല"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> സംരക്ഷിച്ചത്"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s വഴി സ്വയമേവ ബന്ധിപ്പിച്ചു"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"നെറ്റ്‌വർക്ക് റേറ്റിംഗ് ദാതാവുമായി സ്വയം കണക്‌റ്റുചെയ്‌തു"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index f13cb0b..45a831d 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматаар холбогдохгүй"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернет хандалт алга"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> хадгалсан"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s-р автоматаар холбогдсон"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Сүлжээний үнэлгээ үзүүлэгчээр автоматаар холбогдох"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s-р холбогдсон"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index aaf51b3..6cc0130 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -155,14 +155,28 @@
     <item msgid="253388653486517049">", अ‍ॅक्टिव्ह (मीडिया)"</item>
     <item msgid="5001852592115448348">", अ‍ॅक्टिव्ह (फोन)"</item>
   </string-array>
-    <!-- no translation found for select_logd_size_titles:5 (6078203297886482480) -->
+  <string-array name="select_logd_size_titles">
+    <item msgid="1191094707770726722">"बंद"</item>
+    <item msgid="7839165897132179888">"64K"</item>
+    <item msgid="2715700596495505626">"256K"</item>
+    <item msgid="7099386891713159947">"1M"</item>
+    <item msgid="6069075827077845520">"4M"</item>
+    <item msgid="6078203297886482480">"८MB"</item>
+  </string-array>
   <string-array name="select_logd_size_lowram_titles">
     <item msgid="1145807928339101085">"बंद"</item>
     <item msgid="4064786181089783077">"64K"</item>
     <item msgid="3052710745383602630">"256K"</item>
     <item msgid="3691785423374588514">"1M"</item>
   </string-array>
-    <!-- no translation found for select_logd_size_summaries:5 (2983219471251787208) -->
+  <string-array name="select_logd_size_summaries">
+    <item msgid="409235464399258501">"बंद"</item>
+    <item msgid="4195153527464162486">"प्रति लॉग बफर 64K"</item>
+    <item msgid="7464037639415220106">"प्रति लॉग बफर 256K"</item>
+    <item msgid="8539423820514360724">"प्रति लॉग बफर 1M"</item>
+    <item msgid="1984761927103140651">"प्रति लॉग बफर 4M"</item>
+    <item msgid="2983219471251787208">"८MB प्रति लॉग बफर"</item>
+  </string-array>
   <string-array name="select_logpersist_titles">
     <item msgid="704720725704372366">"बंद"</item>
     <item msgid="6014837961827347618">"सर्व"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 72ddc8f..1e69b28 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"स्वयंचलितपणे कनेक्ट करणार नाही"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"इंटरनेट अ‍ॅक्सेस नाही"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे सेव्ह केले"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्क रेटिंग प्रदात्याद्वारे स्वयंचलितपणे कनेक्ट केले"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s द्वारे कनेक्‍ट केले"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 9527793..71c9eea 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Tidak akan menyambung secara automatik"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Tiada akses Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Diselamatkan oleh <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Disambungkan secara automatik melalui %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Disambungkan secara automatik melalui pembekal penilaian rangkaian"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Disambungkan melalui %1$s"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 1dcb3cf..3b3983e 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"အလိုအလျောက်ချိတ်ဆက်မည်မဟုတ်ပါ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"အင်တာနက် ချိတ်ဆက်မှု မရှိပါ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> က သိမ်းဆည်းခဲ့သည်"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ကွန်ရက်အဆင့်သတ်မှတ်ပေးသူ မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 13f69c1..a8c01b3 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Kobler ikke til automatisk"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ingen internettilgang"</string>
     <string name="saved_network" msgid="7143698034077223645">"Lagret av <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisk tilkoblet via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisk tilkoblet via leverandør av nettverksvurdering"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Tilkoblet via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 5795cc9..c285637 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"स्वतः जडान हुने छैन"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"इन्टरनेटमाथिको पहुँच छैन"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा सुरक्षित गरियो"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s मार्फत् स्वतः जडान गरिएको"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्कको दर्जा प्रदायक मार्फत स्वत: जडान गरिएको"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s मार्फत जडित"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 718ce5d..9f4ea68 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Er wordt niet automatisch verbinding gemaakt"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Geen internettoegang"</string>
     <string name="saved_network" msgid="7143698034077223645">"Opgeslagen door \'<xliff:g id="NAME">%1$s</xliff:g>\'"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatisch verbonden via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatisch verbonden via provider van netwerkbeoordelingen"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Verbonden via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 41e84f9..31bd7af 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ସ୍ୱଚାଳିତ ଭାବେ ସଂଯୁକ୍ତ ହେବନାହିଁ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ଇଣ୍ଟରନେଟ୍‌ର କୌଣସି ଆକ୍‌ସେସ୍‌ ନାହିଁ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ଦ୍ୱାରା ସେଭ କରାଯାଇଛି"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲୀ ସଂଯୁକ୍ତ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ନେଟୱର୍କ ମୂଲ୍ୟାୟନ ପ୍ରଦାତାଙ୍କ ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲ୍ୟ ସଂଯୁକ୍ତ"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index c64ee76..c6116aa 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -155,14 +155,28 @@
     <item msgid="253388653486517049">", ਕਿਰਿਆਸ਼ੀਲ (ਮੀਡੀਆ)"</item>
     <item msgid="5001852592115448348">", ਕਿਰਿਆਸ਼ੀਲ (ਫ਼ੋਨ)"</item>
   </string-array>
-    <!-- no translation found for select_logd_size_titles:5 (6078203297886482480) -->
+  <string-array name="select_logd_size_titles">
+    <item msgid="1191094707770726722">"ਬੰਦ"</item>
+    <item msgid="7839165897132179888">"64K"</item>
+    <item msgid="2715700596495505626">"256K"</item>
+    <item msgid="7099386891713159947">"1M"</item>
+    <item msgid="6069075827077845520">"4M"</item>
+    <item msgid="6078203297886482480">"8M"</item>
+  </string-array>
   <string-array name="select_logd_size_lowram_titles">
     <item msgid="1145807928339101085">"ਬੰਦ"</item>
     <item msgid="4064786181089783077">"64K"</item>
     <item msgid="3052710745383602630">"256K"</item>
     <item msgid="3691785423374588514">"1M"</item>
   </string-array>
-    <!-- no translation found for select_logd_size_summaries:5 (2983219471251787208) -->
+  <string-array name="select_logd_size_summaries">
+    <item msgid="409235464399258501">"ਬੰਦ"</item>
+    <item msgid="4195153527464162486">"64K ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="7464037639415220106">"256K ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="8539423820514360724">"1M ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="1984761927103140651">"4M ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="2983219471251787208">"8M ਪ੍ਰਤੀ ਲੌਗ ਬਫ਼ਰ"</item>
+  </string-array>
   <string-array name="select_logpersist_titles">
     <item msgid="704720725704372366">"ਬੰਦ"</item>
     <item msgid="6014837961827347618">"ਸਭ"</item>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index e04e201..f21c4ce 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ਵੱਲੋਂ ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ਨੈੱਟਵਰਕ ਰੇਟਿੰਗ ਪ੍ਰਦਾਨਕ ਰਾਹੀਂ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਇਆ"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index a57e541..c9c4a6c 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nie można połączyć automatycznie"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Brak dostępu do internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Zapisane przez: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatycznie połączono przez: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatycznie połączono przez dostawcę ocen jakości sieci"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Połączono przez %1$s"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index f24b52b..881bccb 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sem acesso à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salva por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Conectado a uma rede limitada"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectado automaticamente via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automaticamente via provedor de avaliação de rede"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 42ad0fe..94cad918 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Não é efetuada uma ligação automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sem acesso à Internet."</string>
     <string name="saved_network" msgid="7143698034077223645">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Ligação estabelecida a uma rede de acesso limitado."</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ligado automaticamente através de %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ligado automaticamente através do fornecedor de classificação de rede"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Ligado através de %1$s"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index f24b52b..881bccb 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -36,6 +36,7 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Sem acesso à Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salva por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="connected_to_metered_access_point" msgid="9179693207918156341">"Conectado a uma rede limitada"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectado automaticamente via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectado automaticamente via provedor de avaliação de rede"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectado via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 0743fe9..4b71085 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nu se va conecta automat"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nu există acces la internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Salvată de <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Conectată automat prin %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Conectată automat prin furnizor de evaluări ale rețelei"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Conectată prin %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index d19438a..4aeb985 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Подключение не будет выполняться автоматически"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Без доступа к Интернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Кто сохранил: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматически подключено к %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматически подключено через автора рейтинга сетей"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Подключено к %1$s"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 15fe8c8..525d423 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"ස්වයංක්‍රිය නැවත සම්බන්ධ නොවනු ඇත"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"අන්තර්ජාල ප්‍රවේශය නැත"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> විසින් සුරකින ලදී"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s හරහා ස්වයංක්‍රියව සම්බන්ධ විය"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"ජාල ශ්‍රේණිගත සපයන්නා හරහා ස්වයංක්‍රියව සම්බන්ධ විය"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s හරහා සම්බන්ධ විය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index ee53b7c..ee9ae6a 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nedôjde k automatickému pripojeniu"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Žiadny prístup k internetu"</string>
     <string name="saved_network" msgid="7143698034077223645">"Uložila aplikácia <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaticky pripojené prostredníctvom %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automaticky pripojené prostredníctvom poskytovateľa hodnotenia siete"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Pripojené prostredníctvom %1$s"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 66d33a7..ff60a32 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Samodejna vnovična vzpostavitev povezave se ne bo izvedla"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ni dostopa do interneta"</string>
     <string name="saved_network" msgid="7143698034077223645">"Shranil(-a): <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Samodejno vzpostavljena povezava prek: %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Samodejno vzpostavljena povezava prek ponudnika ocenjevanja omrežij"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Vzpostavljena povezava prek: %1$s"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index d5c0231..78e6ed6 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Nuk do të lidhet automatikisht"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nuk ka qasje në internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"E ruajtur nga <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Lidhur automatikisht përmes %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Lidhur automatikisht nëpërmjet ofruesit të vlerësimit të rrjetit"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"E lidhur përmes %1$s"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index ce74b84..8bb9277 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Аутоматско повезивање није успело"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Нема приступа интернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аутоматски повезано преко %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аутоматски повезано преко добављача оцене мреже"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Веза је успостављена преко приступне тачке %1$s"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index eacb7a8..03fb223 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Det går inte att ansluta automatiskt"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ingen internetåtkomst"</string>
     <string name="saved_network" msgid="7143698034077223645">"Sparades av <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatiskt ansluten via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatiskt ansluten via leverantör av nätverksbetyg"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Anslutet via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 62ae06b..b95d69c 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -161,7 +161,7 @@
     <item msgid="2715700596495505626">"K256"</item>
     <item msgid="7099386891713159947">"M1"</item>
     <item msgid="6069075827077845520">"M4"</item>
-    <item msgid="6078203297886482480">"M8"</item>
+    <item msgid="6078203297886482480">"MB 8"</item>
   </string-array>
   <string-array name="select_logd_size_lowram_titles">
     <item msgid="1145807928339101085">"Imezimwa"</item>
@@ -175,7 +175,7 @@
     <item msgid="7464037639415220106">"K256 kwa kila akiba ya kumbukumbu"</item>
     <item msgid="8539423820514360724">"M1 kwa kila akiba ya kumbukumbu"</item>
     <item msgid="1984761927103140651">"M4 kwa kila akiba ya kumbukumbu"</item>
-    <item msgid="2983219471251787208">"M8 kwa kila akiba ya kumbukumbu"</item>
+    <item msgid="2983219471251787208">"MB 8 kwa kila akiba ya kumbukumbu"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
     <item msgid="704720725704372366">"Yamezimwa"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index e7045a7..631a413 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Haiwezi kuunganisha kiotomatiki"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Hakuna muunganisho wa intaneti"</string>
     <string name="saved_network" msgid="7143698034077223645">"Ilihifadhiwa na <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Imeunganishwa kiotomatiki kupitia %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Imeunganishwa kiotomatiki kupitia mtoa huduma wa ukadiriaji wa mtandao"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Imeunganishwa kupitia %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 06c7ccb..5796603 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"தானாக இணைக்கப்படாது"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"இண்டர்நெட் அணுகல் இல்லை"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> சேமித்தது"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s மூலம் தானாக இணைக்கப்பட்டது"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"நெட்வொர்க் மதிப்பீடு வழங்குநரால் தானாக இணைக்கப்பட்டது"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s வழியாக இணைக்கப்பட்டது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 5e880a9..9027ca1 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"స్వయంచాలకంగా కనెక్ట్ కాదు"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా సేవ్ చేయబడింది"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"నెట్‌వర్క్ రేటింగ్ ప్రదాత ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 6316452..8358dbb 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"จะไม่เชื่อมต่อโดยอัตโนมัติ"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"เข้าถึงอินเทอร์เน็ตไม่ได้"</string>
     <string name="saved_network" msgid="7143698034077223645">"บันทึกโดย<xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"เชื่อมต่ออัตโนมัติผ่าน %1$s แล้ว"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"เชื่อมต่ออัตโนมัติผ่านผู้ให้บริการการจัดอันดับเครือข่าย"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 0aabbe5..d5250a4 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Hindi awtomatikong kokonekta"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Walang access sa internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Na-save ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Awtomatikong nakakonekta sa pamamagitan ng %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Awtomatikong nakakonekta sa pamamagitan ng provider ng rating ng network"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Nakakonekta sa pamamagitan ng %1$s"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 44c8f13..8e0b889 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Otomatik olarak bağlanma"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"İnternet erişimi yok"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> tarafından kaydedildi"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s üzerinden otomatik olarak bağlı"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Ağ derecelendirme sağlayıcı aracılığıyla otomatik olarak bağlandı"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s üzerinden bağlı"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 7851111..c2f71c3 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Не під’єднуватиметься автоматично"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Немає доступу до Інтернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Збережено додатком <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматично під’єднано через %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматично під’єднано через постачальника оцінки якості мережі"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Під’єднано через %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 82783b3..a0c5f94 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"خودکار طور پر منسلک نہیں ہو گا"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"انٹرنیٹ تک کوئی رسائی نہیں"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> کی جانب سے محفوظ کردہ"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏‎%1$s کے ذریعے از خود منسلک کردہ"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"نیٹ ورک درجہ بندی کے فراہم کنندہ کے ذریعے از خود منسلک"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"‏منسلک بذریعہ ‎%1$s"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index c2a96c6..1fb610b 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Avtomatik ravishda ulanilmaydi"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Internet aloqasi yo‘q"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> tomonidan saqlangan"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s orqali avtomatik ulandi"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Tarmoqlar reytingi muallifi orqali avtomatik ulandi"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s orqali ulangan"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 2596424..1f3ea48 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Sẽ không tự động kết nối"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Không có quyền truy cập Internet"</string>
     <string name="saved_network" msgid="7143698034077223645">"Do <xliff:g id="NAME">%1$s</xliff:g> lưu"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Tự động được kết nối qua %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Tự động được kết nối qua nhà cung cấp dịch vụ xếp hạng mạng"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Được kết nối qua %1$s"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 60afd6d..828d25f 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"无法自动连接"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"无法访问互联网"</string>
     <string name="saved_network" msgid="7143698034077223645">"由“<xliff:g id="NAME">%1$s</xliff:g>”保存"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"已通过%1$s自动连接"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"已自动连接(通过网络评分服务提供方)"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"已通过%1$s连接"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 925f738..54e1f41 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"不會自動連線"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"無法連接互聯網"</string>
     <string name="saved_network" msgid="7143698034077223645">"由「<xliff:g id="NAME">%1$s</xliff:g>」儲存"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"已透過 %1$s 自動連線"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"已透過網絡評分供應商自動連線"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"已透過 %1$s 連線"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index e40d351..b8f1f58 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"無法自動連線"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"沒有可用的網際網路連線"</string>
     <string name="saved_network" msgid="7143698034077223645">"由「<xliff:g id="NAME">%1$s</xliff:g>」儲存"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"已透過 %1$s 自動連線"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"已透過網路評分供應商自動連線"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"已透過 %1$s 連線"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index c304c14..d680b66 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -36,6 +36,8 @@
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Ngeke ize ixhumeke ngokuzenzakalela"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Akukho ukufinyelela kwe-inthanethi"</string>
     <string name="saved_network" msgid="7143698034077223645">"Kulondolozwe ngu-<xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for connected_to_metered_access_point (9179693207918156341) -->
+    <skip />
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Ixhumeke ngokuzenzakalela nge-%1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Kuxhunywe ngokuzenzakalelayo ngomhlinzeki wesilinganiso wenethiwekhi"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"Kuxhumeke nge-%1$s"</string>
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index efd941e..757a90e 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -749,7 +749,8 @@
                  Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
                  Settings.Secure.SUPPRESS_DOZE,
                  Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
-                 Settings.Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT);
+                 Settings.Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT,
+                 Settings.Secure.TRANSFORM_ENABLED);
 
     @Test
     public void systemSettingsBackedUpOrDenied() {
diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml
index 827cf4a..7bc7ba1 100644
--- a/packages/SystemUI/res/drawable/privacy_chip_bg.xml
+++ b/packages/SystemUI/res/drawable/privacy_chip_bg.xml
@@ -16,7 +16,7 @@
 -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="#242424" /> <!-- 14% of white -->
+    <solid android:color="?android:attr/colorAccent" />
     <padding android:paddingTop="@dimen/ongoing_appops_chip_bg_padding"
         android:paddingBottom="@dimen/ongoing_appops_chip_bg_padding" />
     <corners android:radius="@dimen/ongoing_appops_chip_bg_corner_radius" />
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 49f9109..01e54ff 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -31,4 +31,9 @@
 
     <!-- AOD/Lockscreen alternate layout -->
     <bool name="flag_keyguard_layout">false</bool>
+
+    <bool name="flag_brightness_slider">false</bool>
+
+    <!-- People Tile flag -->
+    <bool name="flag_conversations">false</bool>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 036fcf3..78f7966 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -127,7 +127,7 @@
                     }
 
                     // If SHOW_PEOPLE_SPACE is true, enable People Space widget provider.
-                    // TODO(b/170396074): Remove this when we don't need a widget anymore.
+                    // TODO(b/170396074): Migrate to new feature flag (go/silk-flags-howto)
                     try {
                         int showPeopleSpace = Settings.Global.getInt(context.getContentResolver(),
                                 Settings.Global.SHOW_PEOPLE_SPACE, 1);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 055270d..7d06dd6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -23,7 +23,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
 import android.app.TaskStackListener;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -137,7 +136,8 @@
                         mActivityTaskManager.getTasks(1);
                 if (!runningTasks.isEmpty()) {
                     final String topPackage = runningTasks.get(0).topActivity.getPackageName();
-                    if (!topPackage.contentEquals(clientPackage)) {
+                    if (!topPackage.contentEquals(clientPackage)
+                            && !Utils.isSystem(mContext, clientPackage)) {
                         Log.w(TAG, "Evicting client due to: " + topPackage);
                         mCurrentDialog.dismissWithoutCallback(true /* animate */);
                         mCurrentDialog = null;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
index fd5e85a..076c7cb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
@@ -16,13 +16,16 @@
 
 package com.android.systemui.biometrics;
 
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.biometrics.SensorPropertiesInternal;
 import android.os.UserManager;
@@ -116,4 +119,10 @@
 
         return false;
     }
+
+    static boolean isSystem(@NonNull Context context, @Nullable String clientPackage) {
+        final boolean hasPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
+                == PackageManager.PERMISSION_GRANTED;
+        return hasPermission && "android".equals(clientPackage);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 870e714..ec9291e 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -21,6 +21,7 @@
 import android.widget.FrameLayout
 import android.widget.ImageView
 import android.widget.LinearLayout
+import com.android.settingslib.Utils
 import com.android.systemui.R
 
 class OngoingPrivacyChip @JvmOverloads constructor(
@@ -36,8 +37,9 @@
                     R.dimen.ongoing_appops_chip_icon_margin_collapsed)
     private val iconSize =
             context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size)
-    private val iconColor = context.resources.getColor(
-            R.color.status_bar_clock_color, context.theme)
+    private val iconColor = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
+    private val expandedIconColor = Utils
+            .getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse)
     private val sidePadding =
             context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
     private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg)
@@ -73,7 +75,7 @@
             iconsContainer.removeAllViews()
             chipBuilder.generateIcons().forEachIndexed { i, it ->
                 it.mutate()
-                it.setTint(iconColor)
+                it.setTint(if (expanded) expandedIconColor else iconColor)
                 val image = ImageView(context).apply {
                     setImageDrawable(it)
                     scaleType = ImageView.ScaleType.CENTER_INSIDE
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
index 11ee94c..8dcc8b4 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
@@ -17,6 +17,7 @@
 package com.android.systemui.settings.brightness;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.util.settings.SecureSettings;
 
 import javax.inject.Inject;
@@ -28,11 +29,13 @@
 public class BrightnessControllerSettings {
 
     private static final String THICK_BRIGHTNESS_SLIDER = "sysui_thick_brightness";
+    private final FeatureFlags mFeatureFlags;
     private final boolean mUseThickSlider;
     private final boolean mUseMirrorOnThickSlider;
 
     @Inject
-    public BrightnessControllerSettings(SecureSettings settings) {
+    public BrightnessControllerSettings(SecureSettings settings, FeatureFlags featureFlags) {
+        mFeatureFlags = featureFlags;
         mUseThickSlider = settings.getInt(THICK_BRIGHTNESS_SLIDER, 0) != 0;
         mUseMirrorOnThickSlider = settings.getInt(THICK_BRIGHTNESS_SLIDER, 0) != 2;
     }
@@ -41,11 +44,11 @@
     // restart systemui after changing it.
     /** */
     boolean useThickSlider() {
-        return mUseThickSlider;
+        return mUseThickSlider && mFeatureFlags.useNewBrightnessSlider();
     }
 
     /** */
     boolean useMirrorOnThickSlider() {
-        return mUseMirrorOnThickSlider;
+        return !useThickSlider() || (useThickSlider() && mUseMirrorOnThickSlider);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 30b3158..e7b60c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -61,4 +61,13 @@
     public boolean isKeyguardLayoutEnabled() {
         return mFlagReader.isEnabled(R.bool.flag_keyguard_layout);
     }
+
+    /** b/178485354 */
+    public boolean useNewBrightnessSlider() {
+        return mFlagReader.isEnabled(R.bool.flag_brightness_slider);
+    }
+
+    public boolean isPeopleTileEnabled() {
+        return mFlagReader.isEnabled(R.bool.flag_conversations);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 01d3103..e5a960e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -83,6 +83,9 @@
     public static final int STATE_DOT = 1;
     public static final int STATE_HIDDEN = 2;
 
+    /** Maximum allowed width or height for an icon drawable */
+    private static final int MAX_IMAGE_SIZE = 500;
+
     private static final String TAG = "StatusBarIconView";
     private static final Property<StatusBarIconView, Float> ICON_APPEAR_AMOUNT
             = new FloatProperty<StatusBarIconView>("iconAppearAmount") {
@@ -378,6 +381,13 @@
             Log.w(TAG, "No icon for slot " + mSlot + "; " + mIcon.icon);
             return false;
         }
+
+        if (drawable.getIntrinsicWidth() > MAX_IMAGE_SIZE
+                || drawable.getIntrinsicHeight() > MAX_IMAGE_SIZE) {
+            Log.w(TAG, "Drawable is too large " + mIcon);
+            return false;
+        }
+
         if (withClear) {
             setImageDrawable(null);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
index 4fde118..db49e44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
@@ -21,7 +21,6 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
@@ -50,7 +49,6 @@
     private final ShadeListBuilder mListBuilder;
     private final NotifCoordinators mNotifPluggableCoordinators;
     private final NotifInflaterImpl mNotifInflater;
-    private final PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
     private final DumpManager mDumpManager;
     private final ShadeViewManagerFactory mShadeViewManagerFactory;
     private final FeatureFlags mFeatureFlags;
@@ -64,7 +62,6 @@
             ShadeListBuilder listBuilder,
             NotifCoordinators notifCoordinators,
             NotifInflaterImpl notifInflater,
-            PeopleSpaceWidgetManager peopleSpaceWidgetManager,
             DumpManager dumpManager,
             ShadeViewManagerFactory shadeViewManagerFactory,
             FeatureFlags featureFlags) {
@@ -75,7 +72,6 @@
         mNotifPluggableCoordinators = notifCoordinators;
         mDumpManager = dumpManager;
         mNotifInflater = notifInflater;
-        mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
         mShadeViewManagerFactory = shadeViewManagerFactory;
         mFeatureFlags = featureFlags;
     }
@@ -103,7 +99,6 @@
         mListBuilder.attach(mNotifCollection);
         mNotifCollection.attach(mGroupCoalescer);
         mGroupCoalescer.attach(notificationService);
-        mPeopleSpaceWidgetManager.attach(notificationService);
 
         Log.d(TAG, "Notif pipeline initialized");
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 54ce4ed..0ad6507 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -18,6 +18,7 @@
 
 import android.service.notification.StatusBarNotification
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption
 import com.android.systemui.statusbar.FeatureFlags
 import com.android.systemui.statusbar.NotificationListener
@@ -73,7 +74,8 @@
     private val headsUpController: HeadsUpController,
     private val headsUpViewBinder: HeadsUpViewBinder,
     private val clickerBuilder: NotificationClicker.Builder,
-    private val animatedImageNotificationManager: AnimatedImageNotificationManager
+    private val animatedImageNotificationManager: AnimatedImageNotificationManager,
+    private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager
 ) : NotificationsController {
 
     override fun initialize(
@@ -126,6 +128,10 @@
 
             entryManager.attach(notificationListener)
         }
+
+        if (featureFlags.isPeopleTileEnabled) {
+            peopleSpaceWidgetManager.attach(notificationListener)
+        }
     }
 
     override fun dump(
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 81ac21c..71835b6 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -252,6 +252,7 @@
             public void onStop() {
                 mSysUiMainExecutor.execute(() -> {
                     if (oneHanded.isOneHandedEnabled()) {
+                        // Log metrics for 3-button navigation mode.
                         oneHanded.stopOneHanded(
                                 OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
                     } else if (oneHanded.isSwipeToNotificationEnabled()) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 71f146b..f31639c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -35,6 +35,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
 import android.os.UserHandle;
@@ -121,4 +122,13 @@
         assertEquals("Transparent backgrounds should fallback to drawable color",
                 color, mIconView.getStaticDrawableColor());
     }
+
+    @Test
+    public void testGiantImageNotAllowed() {
+        Bitmap largeBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
+        Icon icon = Icon.createWithBitmap(largeBitmap);
+        StatusBarIcon largeIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+                icon, 0, 0, "");
+        assertFalse(mIconView.set(largeIcon));
+    }
 }
\ No newline at end of file
diff --git a/services/Android.bp b/services/Android.bp
index f6bb72a..1970b7d 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -36,6 +36,7 @@
         ":services.usb-sources",
         ":services.voiceinteraction-sources",
         ":services.wifi-sources",
+        ":service-media-s-sources", // TODO (b/177640454)
         ":service-permission-sources",
         ":service-statsd-sources",
     ],
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 04e08ae..e4d9724 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -17,9 +17,14 @@
 
 package com.android.server.companion;
 
+import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES;
+import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED;
+import static android.content.Context.BIND_IMPORTANT;
+
 import static com.android.internal.util.CollectionUtils.emptyIfNull;
 import static com.android.internal.util.CollectionUtils.find;
 import static com.android.internal.util.CollectionUtils.forEach;
+import static com.android.internal.util.CollectionUtils.map;
 import static com.android.internal.util.FunctionalUtils.uncheckExceptions;
 import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkNotNull;
@@ -40,12 +45,18 @@
 import android.app.role.RoleManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
 import android.companion.Association;
 import android.companion.AssociationRequest;
 import android.companion.CompanionDeviceManager;
+import android.companion.CompanionDeviceService;
 import android.companion.DeviceNotAssociatedException;
 import android.companion.ICompanionDeviceDiscoveryService;
 import android.companion.ICompanionDeviceManager;
+import android.companion.ICompanionDeviceService;
 import android.companion.IFindDeviceCallback;
 import android.content.ComponentName;
 import android.content.Context;
@@ -77,6 +88,7 @@
 import android.provider.Settings;
 import android.provider.SettingsStringUtil.ComponentNameSet;
 import android.text.BidiFormatter;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.ExceptionUtils;
@@ -115,6 +127,7 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -135,9 +148,14 @@
             CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
             ".DeviceDiscoveryService");
 
+    private static final long DEVICE_DISAPPEARED_TIMEOUT_MS = 10 * 1000;
+    private static final long DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS = 10 * 60 * 1000;
+
     private static final boolean DEBUG = false;
     private static final String LOG_TAG = "CompanionDeviceManagerService";
 
+    private static final long PAIR_WITHOUT_PROMPT_WINDOW_MS = 10 * 60 * 1000; // 10 min
+
     private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
     private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
 
@@ -146,18 +164,24 @@
     private static final String XML_ATTR_PACKAGE = "package";
     private static final String XML_ATTR_DEVICE = "device";
     private static final String XML_ATTR_PROFILE = "profile";
-    private static final String XML_ATTR_PERSISTENT_PROFILE_GRANTS = "persistent_profile_grants";
+    private static final String XML_ATTR_NOTIFY_DEVICE_NEARBY = "notify_device_nearby";
+    private static final String XML_ATTR_TIME_APPROVED = "time_approved";
     private static final String XML_FILE_NAME = "companion_device_manager_associations.xml";
 
     private final CompanionDeviceManagerImpl mImpl;
     private final ConcurrentMap<Integer, AtomicFile> mUidToStorage = new ConcurrentHashMap<>();
     private PowerWhitelistManager mPowerWhitelistManager;
     private PerUser<ServiceConnector<ICompanionDeviceDiscoveryService>> mServiceConnectors;
+    /** userId -> packageName -> serviceConnector */
+    private PerUser<ArrayMap<String, ServiceConnector<ICompanionDeviceService>>>
+            mDeviceListenerServiceConnectors;
     private IAppOpsService mAppOpsManager;
     private RoleManager mRoleManager;
     private BluetoothAdapter mBluetoothAdapter;
+    private UserManager mUserManager;
 
     private IFindDeviceCallback mFindDeviceCallback;
+    private ScanCallback mBleScanCallback = new BleScanCallback();
     private AssociationRequest mRequest;
     private String mCallingPackage;
     private AndroidFuture<Association> mOngoingDeviceDiscovery;
@@ -166,8 +190,14 @@
     private BluetoothDeviceConnectedListener mBluetoothDeviceConnectedListener =
             new BluetoothDeviceConnectedListener();
     private List<String> mCurrentlyConnectedDevices = new ArrayList<>();
+    private ArrayMap<String, Date> mDevicesLastNearby = new ArrayMap<>();
+    private UnbindDeviceListenersRunnable
+            mUnbindDeviceListenersRunnable = new UnbindDeviceListenersRunnable();
+    private ArrayMap<String, TriggerDeviceDisappearedRunnable> mTriggerDeviceDisappearedRunnables =
+            new ArrayMap<>();
 
     private final Object mLock = new Object();
+    private final Handler mMainHandler = Handler.getMain();
 
     /** userId -> [association] */
     @GuardedBy("mLock")
@@ -189,6 +219,7 @@
         mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mPermissionControllerManager = requireNonNull(
                 context.getSystemService(PermissionControllerManager.class));
+        mUserManager = context.getSystemService(UserManager.class);
 
         Intent serviceIntent = new Intent().setComponent(SERVICE_TO_BIND_TO);
         mServiceConnectors = new PerUser<ServiceConnector<ICompanionDeviceDiscoveryService>>() {
@@ -201,6 +232,16 @@
             }
         };
 
+        mDeviceListenerServiceConnectors = new PerUser<ArrayMap<String,
+                ServiceConnector<ICompanionDeviceService>>>() {
+            @NonNull
+            @Override
+            protected ArrayMap<String, ServiceConnector<ICompanionDeviceService>> create(
+                    int userId) {
+                return new ArrayMap<>();
+            }
+        };
+
         registerPackageMonitor();
     }
 
@@ -208,10 +249,13 @@
         new PackageMonitor() {
             @Override
             public void onPackageRemoved(String packageName, int uid) {
+                int userId = getChangingUserId();
                 updateAssociations(
                         as -> CollectionUtils.filter(as,
                                 a -> !Objects.equals(a.getPackageName(), packageName)),
-                        getChangingUserId());
+                        userId);
+
+                unbindDevicePresenceListener(packageName, userId);
             }
 
             @Override
@@ -225,6 +269,15 @@
         }.register(getContext(), FgThread.get().getLooper(), UserHandle.ALL, true);
     }
 
+    private void unbindDevicePresenceListener(String packageName, int userId) {
+        ServiceConnector<ICompanionDeviceService> deviceListener =
+                mDeviceListenerServiceConnectors.forUser(userId)
+                        .remove(packageName);
+        if (deviceListener != null) {
+            deviceListener.unbind();
+        }
+    }
+
     @Override
     public void onStart() {
         publishBinderService(Context.COMPANION_DEVICE_SERVICE, mImpl);
@@ -238,6 +291,9 @@
                 mBluetoothAdapter.registerBluetoothConnectionCallback(
                         getContext().getMainExecutor(),
                         mBluetoothDeviceConnectedListener);
+                initBleScanning();
+            } else {
+                Log.w(LOG_TAG, "No BluetoothAdapter available");
             }
         }
     }
@@ -287,7 +343,7 @@
 
     @Override
     public void binderDied() {
-        Handler.getMain().post(this::cleanup);
+        mMainHandler.post(this::cleanup);
     }
 
     private void cleanup() {
@@ -399,7 +455,7 @@
                 checkCallerIsSystemOr(callingPackage, userId);
                 checkUsesFeature(callingPackage, getCallingUserId());
             }
-            return new ArrayList<>(CollectionUtils.map(
+            return new ArrayList<>(map(
                     getAllAssociations(userId, callingPackage),
                     a -> a.getDeviceMacAddress()));
         }
@@ -506,22 +562,18 @@
         public void registerDevicePresenceListenerService(
                 String packageName, String deviceAddress)
                 throws RemoteException {
-            checkCanRegisterObserverService(packageName, deviceAddress);
-
-            //TODO(eugenesusla) implement
+            registerDevicePresenceListenerActive(packageName, deviceAddress, true);
         }
 
         @Override
         public void unregisterDevicePresenceListenerService(
                 String packageName, String deviceAddress)
                 throws RemoteException {
-            checkCanRegisterObserverService(packageName, deviceAddress);
-
-            //TODO(eugenesusla) implement
+            registerDevicePresenceListenerActive(packageName, deviceAddress, false);
         }
 
-        private void checkCanRegisterObserverService(String packageName, String deviceAddress)
-                throws RemoteException {
+        private void registerDevicePresenceListenerActive(String packageName, String deviceAddress,
+                boolean active) throws RemoteException {
             getContext().enforceCallingOrSelfPermission(
                     android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE,
                     "[un]registerDevicePresenceListenerService");
@@ -537,6 +589,21 @@
                         + " is not associated with device " + deviceAddress
                         + " for user " + userId));
             }
+
+            updateAssociations(associations -> map(associations, association -> {
+                if (Objects.equals(association.getPackageName(), packageName)
+                        && Objects.equals(association.getDeviceMacAddress(), deviceAddress)) {
+                    return new Association(
+                            association.getUserId(),
+                            association.getDeviceMacAddress(),
+                            association.getPackageName(),
+                            association.getDeviceProfile(),
+                            active /* notifyOnDeviceNearby */,
+                            association.getTimeApprovedMs());
+                } else {
+                    return association;
+                }
+            }));
         }
 
         private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
@@ -565,6 +632,15 @@
         }
 
         @Override
+        public boolean canPairWithoutPrompt(
+                String packageName, String deviceMacAddress, int userId) {
+            return CollectionUtils.any(
+                    getAllAssociations(userId, packageName, deviceMacAddress),
+                    a -> System.currentTimeMillis() - a.getTimeApprovedMs()
+                            < PAIR_WITHOUT_PROMPT_WINDOW_MS);
+        }
+
+        @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
                 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
                 throws RemoteException {
@@ -693,6 +769,10 @@
         if (mCurrentlyConnectedDevices.contains(association.getDeviceMacAddress())) {
             grantDeviceProfile(association);
         }
+
+        if (association.isNotifyOnDeviceNearby()) {
+            restartBleScan();
+        }
     }
 
     private void exemptFromAutoRevoke(String packageName, int uid) {
@@ -795,10 +875,12 @@
                                         association.getDeviceMacAddress());
                         if (association.getDeviceProfile() != null) {
                             tag.attribute(null, XML_ATTR_PROFILE, association.getDeviceProfile());
-                            tag.attribute(null, XML_ATTR_PERSISTENT_PROFILE_GRANTS,
+                            tag.attribute(null, XML_ATTR_NOTIFY_DEVICE_NEARBY,
                                     Boolean.toString(
-                                            association.isKeepProfilePrivilegesWhenDeviceAway()));
+                                            association.isNotifyOnDeviceNearby()));
                         }
+                        tag.attribute(null, XML_ATTR_TIME_APPROVED,
+                                Long.toString(association.getTimeApprovedMs()));
                         tag.endTag(null, XML_TAG_ASSOCIATION);
                     });
 
@@ -838,13 +920,29 @@
         return getContext().getSystemService(UserManager.class).getUsers();
     }
 
-    @Nullable
     private Set<Association> getAllAssociations(int userId, @Nullable String packageFilter) {
         return CollectionUtils.filter(
                 getAllAssociations(userId),
                 a -> Objects.equals(packageFilter, a.getPackageName()));
     }
 
+    private Set<Association> getAllAssociations() {
+        ArraySet<Association> result = new ArraySet<>();
+        for (UserInfo user : mUserManager.getAliveUsers()) {
+            result.addAll(getAllAssociations(user.id));
+        }
+        return result;
+    }
+
+
+    private Set<Association> getAllAssociations(
+            int userId, @Nullable String packageFilter, @Nullable String addressFilter) {
+        return CollectionUtils.filter(
+                getAllAssociations(userId),
+                a -> Objects.equals(packageFilter, a.getPackageName())
+                        && Objects.equals(addressFilter, a.getDeviceMacAddress()));
+    }
+
     private Set<Association> readAllAssociations(int userId) {
         final AtomicFile file = getStorageFileForUser(userId);
 
@@ -865,13 +963,15 @@
 
                     final String profile = parser.getAttributeValue(null, XML_ATTR_PROFILE);
                     final boolean persistentGrants = Boolean.valueOf(
-                            parser.getAttributeValue(null, XML_ATTR_PERSISTENT_PROFILE_GRANTS));
+                            parser.getAttributeValue(null, XML_ATTR_NOTIFY_DEVICE_NEARBY));
+                    final long timeApproved = parseLongOrDefault(
+                            parser.getAttributeValue(null, XML_ATTR_TIME_APPROVED), 0L);
 
                     if (appPackage == null || deviceAddress == null) continue;
 
                     result = ArrayUtils.add(result,
                             new Association(userId, deviceAddress, appPackage,
-                                    profile, persistentGrants));
+                                    profile, persistentGrants, timeApproved));
                 }
                 return result;
             } catch (XmlPullParserException | IOException e) {
@@ -896,6 +996,8 @@
                 }
             }
         }
+
+        onDeviceNearby(address);
     }
 
     private void grantDeviceProfile(Association association) {
@@ -919,6 +1021,210 @@
 
     void onDeviceDisconnected(String address) {
         mCurrentlyConnectedDevices.remove(address);
+
+        onDeviceDisappeared(address);
+    }
+
+    private ServiceConnector<ICompanionDeviceService> getDeviceListenerServiceConnector(
+            Association a) {
+        return mDeviceListenerServiceConnectors.forUser(a.getUserId()).computeIfAbsent(
+                a.getPackageName(),
+                pkg -> new ServiceConnector.Impl<>(getContext(),
+                        new Intent(CompanionDeviceService.SERVICE_INTERFACE),
+                        BIND_IMPORTANT,
+                        a.getUserId(),
+                        ICompanionDeviceService.Stub::asInterface));
+    }
+
+    private class BleScanCallback extends ScanCallback {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onScanResult(callbackType = "
+                        + callbackType + ", result = " + result + ")");
+            }
+
+            onDeviceNearby(result.getDevice().getAddress());
+        }
+
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            for (int i = 0, size = results.size(); i < size; i++) {
+                onScanResult(CALLBACK_TYPE_ALL_MATCHES, results.get(i));
+            }
+        }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            if (errorCode == SCAN_FAILED_ALREADY_STARTED) {
+                // ignore - this might happen if BT tries to auto-restore scans for us in the
+                // future
+            } else {
+                Log.wtf(LOG_TAG, "Failed to start BLE scan: error " + errorCode);
+            }
+        }
+    }
+
+    private class UnbindDeviceListenersRunnable implements Runnable {
+
+        public String getJobId(String address) {
+            return "CDM_deviceGone_unbind_" + address;
+        }
+
+        @Override
+        public void run() {
+            int size = mDevicesLastNearby.size();
+            for (int i = 0; i < size; i++) {
+                String address = mDevicesLastNearby.keyAt(i);
+                Date lastNearby = mDevicesLastNearby.valueAt(i);
+
+                if (System.currentTimeMillis() - lastNearby.getTime()
+                        >= DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS) {
+                    for (Association association : getAllAssociations(address)) {
+                        if (association.isNotifyOnDeviceNearby()) {
+                            getDeviceListenerServiceConnector(association).unbind();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private class TriggerDeviceDisappearedRunnable implements Runnable {
+
+        private final String mAddress;
+
+        TriggerDeviceDisappearedRunnable(String address) {
+            mAddress = address;
+        }
+
+        public void schedule() {
+            mMainHandler.removeCallbacks(this);
+            mMainHandler.postDelayed(this, this, DEVICE_DISAPPEARED_TIMEOUT_MS);
+        }
+
+        @Override
+        public void run() {
+            onDeviceDisappeared(mAddress);
+        }
+    }
+
+    private Set<Association> getAllAssociations(String deviceAddress) {
+        List<UserInfo> aliveUsers = mUserManager.getAliveUsers();
+        Set<Association> result = new ArraySet<>();
+        for (int i = 0, size = aliveUsers.size(); i < size; i++) {
+            UserInfo user = aliveUsers.get(i);
+            for (Association association : getAllAssociations(user.id)) {
+                if (Objects.equals(association.getDeviceMacAddress(), deviceAddress)) {
+                    result.add(association);
+                }
+            }
+        }
+        return result;
+    }
+
+    private void onDeviceNearby(String address) {
+        Date timestamp = new Date();
+        mDevicesLastNearby.put(address, timestamp);
+
+        cancelUnbindDeviceListener(address);
+
+        mTriggerDeviceDisappearedRunnables
+                .computeIfAbsent(address, addr -> new TriggerDeviceDisappearedRunnable(address))
+                .schedule();
+
+        for (Association association : getAllAssociations(address)) {
+            if (association.isNotifyOnDeviceNearby()) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Device " + address
+                            + " managed by " + association.getPackageName()
+                            + " is nearby on " + timestamp);
+                }
+                getDeviceListenerServiceConnector(association).run(
+                        service -> service.onDeviceAppeared(association.getDeviceMacAddress()));
+            }
+        }
+    }
+
+    private void onDeviceDisappeared(String address) {
+        boolean hasDeviceListeners = false;
+        for (Association association : getAllAssociations(address)) {
+            if (association.isNotifyOnDeviceNearby()) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Device " + address
+                            + " managed by " + association.getPackageName()
+                            + " disappeared; last seen on " + mDevicesLastNearby.get(address));
+                }
+
+                getDeviceListenerServiceConnector(association).run(
+                        service -> service.onDeviceDisappeared(address));
+                hasDeviceListeners = true;
+            }
+        }
+
+        cancelUnbindDeviceListener(address);
+        if (hasDeviceListeners) {
+            mMainHandler.postDelayed(
+                    mUnbindDeviceListenersRunnable,
+                    mUnbindDeviceListenersRunnable.getJobId(address),
+                    DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS);
+        }
+    }
+
+    private void cancelUnbindDeviceListener(String address) {
+        mMainHandler.removeCallbacks(
+                mUnbindDeviceListenersRunnable, mUnbindDeviceListenersRunnable.getJobId(address));
+    }
+
+    private void initBleScanning() {
+        boolean bluetoothReady = mBluetoothAdapter.registerServiceLifecycleCallback(
+                new BluetoothAdapter.ServiceLifecycleCallback() {
+                    @Override
+                    public void onBluetoothServiceUp() {
+                        Log.i(LOG_TAG, "Bluetooth stack is up");
+                        startBleScan();
+                    }
+
+                    @Override
+                    public void onBluetoothServiceDown() {
+                        Log.w(LOG_TAG, "Bluetooth stack is down");
+                    }
+                });
+        if (bluetoothReady) {
+            startBleScan();
+        }
+    }
+
+    void startBleScan() {
+        List<ScanFilter> filters = getBleScanFilters();
+        if (filters.isEmpty()) {
+            return;
+        }
+        mBluetoothAdapter.getBluetoothLeScanner().startScan(
+                filters,
+                new ScanSettings.Builder().setScanMode(SCAN_MODE_BALANCED).build(),
+                mBleScanCallback);
+    }
+
+    void restartBleScan() {
+        mBluetoothAdapter.getBluetoothLeScanner().stopScan(mBleScanCallback);
+        startBleScan();
+    }
+
+    private List<ScanFilter> getBleScanFilters() {
+        ArrayList<ScanFilter> result = new ArrayList<>();
+        ArraySet<String> addressesSeen = new ArraySet<>();
+        for (Association association : getAllAssociations()) {
+            String address = association.getDeviceMacAddress();
+            if (addressesSeen.contains(address)) {
+                continue;
+            }
+            if (association.isNotifyOnDeviceNearby()) {
+                result.add(new ScanFilter.Builder().setDeviceAddress(address).build());
+                addressesSeen.add(address);
+            }
+        }
+        return result;
     }
 
     private AndroidFuture<String> getDeviceProfilePermissionDescription(String deviceProfile) {
@@ -926,7 +1232,7 @@
         mPermissionControllerManager.getPrivilegesDescriptionStringForProfile(
                 deviceProfile, FgThread.getExecutor(), desc -> {
                         try {
-                            result.complete(requireNonNull(desc));
+                            result.complete(desc);
                         } catch (Exception e) {
                             result.completeExceptionally(e);
                         }
@@ -934,6 +1240,15 @@
         return result;
     }
 
+    private static long parseLongOrDefault(String str, long def) {
+        try {
+            return Long.parseLong(str);
+        } catch (NumberFormatException e) {
+            Log.w(LOG_TAG, "Failed to parse", e);
+            return def;
+        }
+    }
+
     private class ShellCmd extends ShellCommand {
         public static final String USAGE = "help\n"
                 + "list USER_ID\n"
@@ -962,7 +1277,8 @@
                         int userId = getNextArgInt();
                         String pkg = getNextArgRequired();
                         String address = getNextArgRequired();
-                        addAssociation(new Association(userId, address, pkg, null, false));
+                        addAssociation(new Association(userId, address, pkg, null, false,
+                                System.currentTimeMillis()));
                     }
                     break;
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 0412f08..7d65156 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -48,6 +48,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
@@ -482,14 +483,21 @@
         }
     }
 
-    private @Nullable VolumeInfo findStorageForUuid(String volumeUuid) {
+    private @Nullable VolumeInfo findStorageForUuidAsUser(String volumeUuid,
+            @UserIdInt int userId) {
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
-            return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL + ";" + 0);
+            return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL + ";" + userId);
         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
             return storage.getPrimaryPhysicalVolume();
         } else {
-            return storage.findEmulatedForPrivate(storage.findVolumeByUuid(volumeUuid));
+            VolumeInfo info = storage.findVolumeByUuid(volumeUuid);
+            if (info == null) {
+                Slog.w(TAG, "findStorageForUuidAsUser cannot find volumeUuid:" + volumeUuid);
+                return null;
+            }
+            String emulatedUuid = info.getId().replace("private", "emulated") + ";" + userId;
+            return storage.findVolumeById(emulatedUuid);
         }
     }
 
@@ -2605,8 +2613,9 @@
                 return;
 
             } else {
-                from = findStorageForUuid(mPrimaryStorageUuid);
-                to = findStorageForUuid(volumeUuid);
+                int currentUserId = mCurrentUserId;
+                from = findStorageForUuidAsUser(mPrimaryStorageUuid, currentUserId);
+                to = findStorageForUuidAsUser(volumeUuid, currentUserId);
 
                 if (from == null) {
                     Slog.w(TAG, "Failing move due to missing from volume " + mPrimaryStorageUuid);
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index 6905b3d..6851d71 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -90,6 +90,7 @@
             int userId, PromptInfo promptInfo, String opPackageName,
             boolean checkDevicePolicyManager)
             throws RemoteException {
+
         final boolean confirmationRequested = promptInfo.isConfirmationRequested();
         final boolean biometricRequested = Utils.isBiometricRequested(promptInfo);
         final int requestedStrength = Utils.getPublicBiometricStrength(promptInfo);
@@ -111,7 +112,7 @@
 
                 @AuthenticatorStatus int status = getStatusForBiometricAuthenticator(
                         devicePolicyManager, settingObserver, sensor, userId, opPackageName,
-                        checkDevicePolicyManager, requestedStrength);
+                        checkDevicePolicyManager, requestedStrength, promptInfo.getSensorId());
 
                 Slog.d(TAG, "Package: " + opPackageName
                         + " Sensor ID: " + sensor.id
@@ -141,7 +142,11 @@
             DevicePolicyManager devicePolicyManager,
             BiometricService.SettingObserver settingObserver,
             BiometricSensor sensor, int userId, String opPackageName,
-            boolean checkDevicePolicyManager, int requestedStrength) {
+            boolean checkDevicePolicyManager, int requestedStrength, int requestedSensorId) {
+
+        if (requestedSensorId != BiometricManager.SENSOR_ID_ANY && sensor.id != requestedSensorId) {
+            return BIOMETRIC_NO_HARDWARE;
+        }
 
         final boolean wasStrongEnough =
                 Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength);
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index d87af42..5cd0bbf 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -399,10 +399,15 @@
         }
     }
 
-    public static boolean isKeyguard(Context context, String clientPackage) {
-        final boolean hasPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
-                == PackageManager.PERMISSION_GRANTED;
-
+    /**
+     * Checks if a client package matches Keyguard and can perform internal biometric operations.
+     *
+     * @param context The system context.
+     * @param clientPackage The name of the package to be checked against Keyguard.
+     * @return Whether the given package matches Keyguard.
+     */
+    public static boolean isKeyguard(@NonNull Context context, @Nullable String clientPackage) {
+        final boolean hasPermission = hasInternalPermission(context);
         final ComponentName keyguardComponent = ComponentName.unflattenFromString(
                 context.getResources().getString(R.string.config_keyguardComponent));
         final String keyguardPackage = keyguardComponent != null
@@ -410,6 +415,34 @@
         return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage);
     }
 
+    /**
+     * Checks if a client package matches the Android system and can perform internal biometric
+     * operations.
+     *
+     * @param context The system context.
+     * @param clientPackage The name of the package to be checked against the Android system.
+     * @return Whether the given package matches the Android system.
+     */
+    public static boolean isSystem(@NonNull Context context, @Nullable String clientPackage) {
+        return hasInternalPermission(context) && "android".equals(clientPackage);
+    }
+
+    /**
+     * Checks if a client package matches Settings and can perform internal biometric operations.
+     *
+     * @param context The system context.
+     * @param clientPackage The name of the package to be checked against Settings.
+     * @return Whether the given package matches Settings.
+     */
+    public static boolean isSettings(@NonNull Context context, @Nullable String clientPackage) {
+        return hasInternalPermission(context) && "com.android.settings".equals(clientPackage);
+    }
+
+    private static boolean hasInternalPermission(@NonNull Context context) {
+        return context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
     public static String getClientName(@Nullable BaseClientMonitor client) {
         return client != null ? client.getClass().getSimpleName() : "null";
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 14433fb..0536e78 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -149,9 +149,10 @@
                 pm.incrementAuthForUser(getTargetUserId(), authenticated);
             }
 
-            // Ensure authentication only succeeds if the client activity is on top or is keyguard.
+            // Ensure authentication only succeeds if the client activity is on top.
             boolean isBackgroundAuth = false;
-            if (authenticated && !Utils.isKeyguard(getContext(), getOwnerString())) {
+            if (authenticated && !Utils.isKeyguard(getContext(), getOwnerString())
+                    && !Utils.isSystem(getContext(), getOwnerString())) {
                 final List<ActivityManager.RunningTaskInfo> tasks =
                         mActivityTaskManager.getTasks(1);
                 if (tasks == null || tasks.isEmpty()) {
@@ -166,7 +167,7 @@
                         final String topPackage = topActivity.getPackageName();
                         if (!topPackage.contentEquals(getOwnerString())) {
                             Slog.e(TAG, "Background authentication detected, top: " + topPackage
-                                    + ", client: " + this);
+                                    + ", client: " + getOwnerString());
                             isBackgroundAuth = true;
                         }
                     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 0265cb9..686f9f5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -25,6 +25,10 @@
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.Manifest.permission.USE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
+import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -32,6 +36,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.IBiometricSensorReceiver;
 import android.hardware.biometrics.IBiometricService;
@@ -49,6 +54,7 @@
 import android.hardware.fingerprint.IUdfpsOverlayController;
 import android.os.Binder;
 import android.os.Build;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Process;
@@ -80,6 +86,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * A service to manage multiple clients that want to access the fingerprint HAL API.
@@ -219,8 +226,8 @@
         @SuppressWarnings("deprecation")
         @Override // Binder call
         public void authenticate(final IBinder token, final long operationId,
-                @FingerprintManager.SensorId final int sensorId, final int userId,
-                final IFingerprintServiceReceiver receiver, final String opPackageName) {
+                final int sensorId, final int userId, final IFingerprintServiceReceiver receiver,
+                final String opPackageName) {
             final int callingUid = Binder.getCallingUid();
             final int callingPid = Binder.getCallingPid();
             final int callingUserId = UserHandle.getCallingUserId();
@@ -236,7 +243,7 @@
             final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);
 
             // Clear calling identity when checking LockPatternUtils for StrongAuth flags.
-            final long identity = Binder.clearCallingIdentity();
+            long identity = Binder.clearCallingIdentity();
             try {
                 if (isKeyguard && Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
                     // If this happens, something in KeyguardUpdateMonitor is wrong.
@@ -266,9 +273,101 @@
                 return;
             }
 
-            provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
-                    0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
-                    restricted, statsClient, isKeyguard);
+            final FingerprintSensorPropertiesInternal sensorProps =
+                    provider.second.getSensorProperties(sensorId);
+            if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
+                    && sensorProps != null && sensorProps.isAnyUdfpsType()) {
+                identity = Binder.clearCallingIdentity();
+                try {
+                    authenticateWithPrompt(operationId, sensorProps, userId, receiver);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            } else {
+                provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
+                        0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
+                        restricted, statsClient, isKeyguard);
+            }
+        }
+
+        private void authenticateWithPrompt(
+                final long operationId,
+                @NonNull final FingerprintSensorPropertiesInternal props,
+                final int userId,
+                final IFingerprintServiceReceiver receiver) {
+
+            final Context context = getUiContext();
+            final Executor executor = context.getMainExecutor();
+
+            final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(context)
+                    .setTitle(context.getString(R.string.biometric_dialog_default_title))
+                    .setSubtitle(context.getString(R.string.fingerprint_dialog_default_subtitle))
+                    .setNegativeButton(
+                            context.getString(R.string.cancel),
+                            executor,
+                            (dialog, which) -> {
+                                try {
+                                    receiver.onError(
+                                            FINGERPRINT_ERROR_USER_CANCELED, 0 /* vendorCode */);
+                                } catch (RemoteException e) {
+                                    Slog.e(TAG, "Remote exception in negative button onClick()", e);
+                                }
+                            })
+                    .setSensorId(props.sensorId)
+                    .build();
+
+            final BiometricPrompt.AuthenticationCallback promptCallback =
+                    new BiometricPrompt.AuthenticationCallback() {
+                        @Override
+                        public void onAuthenticationError(int errorCode, CharSequence errString) {
+                            try {
+                                if (FingerprintUtils.isKnownErrorCode(errorCode)) {
+                                    receiver.onError(errorCode, 0 /* vendorCode */);
+                                } else {
+                                    receiver.onError(FINGERPRINT_ERROR_VENDOR, errorCode);
+                                }
+                            } catch (RemoteException e) {
+                                Slog.e(TAG, "Remote exception in onAuthenticationError()", e);
+                            }
+                        }
+
+                        @Override
+                        public void onAuthenticationSucceeded(
+                                BiometricPrompt.AuthenticationResult result) {
+                            final Fingerprint fingerprint = new Fingerprint("", 0, 0L);
+                            final boolean isStrong = props.sensorStrength == STRENGTH_STRONG;
+                            try {
+                                receiver.onAuthenticationSucceeded(fingerprint, userId, isStrong);
+                            } catch (RemoteException e) {
+                                Slog.e(TAG, "Remote exception in onAuthenticationSucceeded()", e);
+                            }
+                        }
+
+                        @Override
+                        public void onAuthenticationFailed() {
+                            try {
+                                receiver.onAuthenticationFailed();
+                            } catch (RemoteException e) {
+                                Slog.e(TAG, "Remote exception in onAuthenticationFailed()", e);
+                            }
+                        }
+
+                        @Override
+                        public void onAuthenticationAcquired(int acquireInfo) {
+                            try {
+                                if (FingerprintUtils.isKnownAcquiredCode(acquireInfo)) {
+                                    receiver.onAcquired(acquireInfo, 0 /* vendorCode */);
+                                } else {
+                                    receiver.onAcquired(FINGERPRINT_ACQUIRED_VENDOR, acquireInfo);
+                                }
+                            } catch (RemoteException e) {
+                                Slog.e(TAG, "Remote exception in onAuthenticationAcquired()", e);
+                            }
+                        }
+                    };
+
+            biometricPrompt.authenticateUserForOperation(
+                    new CancellationSignal(), executor, promptCallback, userId, operationId);
         }
 
         @Override
@@ -374,6 +473,7 @@
         @Override // Binder call
         public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
                 final String opPackageName) {
+
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final ServiceProvider provider = getProviderForSensor(sensorId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
index dc6fd3a..d69151d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
@@ -16,8 +16,18 @@
 
 package com.android.server.biometrics.sensors.fingerprint;
 
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMAGER_DIRTY;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_INSUFFICIENT;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_FAST;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_SLOW;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
+
 import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.biometrics.fingerprint.V2_1.FingerprintError;
 import android.hardware.fingerprint.Fingerprint;
 import android.text.TextUtils;
 import android.util.SparseArray;
@@ -138,5 +148,51 @@
             return state;
         }
     }
+
+    /**
+     * Checks if the given error code corresponds to a known fingerprint error.
+     *
+     * @param errorCode The error code to be checked.
+     * @return Whether the error code corresponds to a known error.
+     */
+    public static boolean isKnownErrorCode(int errorCode) {
+        switch (errorCode) {
+            case FingerprintError.ERROR_HW_UNAVAILABLE:
+            case FingerprintError.ERROR_UNABLE_TO_PROCESS:
+            case FingerprintError.ERROR_TIMEOUT:
+            case FingerprintError.ERROR_NO_SPACE:
+            case FingerprintError.ERROR_CANCELED:
+            case FingerprintError.ERROR_UNABLE_TO_REMOVE:
+            case FingerprintError.ERROR_LOCKOUT:
+            case FingerprintError.ERROR_VENDOR:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks if the given acquired code corresponds to a known fingerprint error.
+     *
+     * @param acquiredCode The acquired code to be checked.
+     * @return Whether the acquired code corresponds to a known error.
+     */
+    public static boolean isKnownAcquiredCode(int acquiredCode) {
+        switch (acquiredCode) {
+            case FINGERPRINT_ACQUIRED_GOOD:
+            case FINGERPRINT_ACQUIRED_PARTIAL:
+            case FINGERPRINT_ACQUIRED_INSUFFICIENT:
+            case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
+            case FINGERPRINT_ACQUIRED_TOO_SLOW:
+            case FINGERPRINT_ACQUIRED_TOO_FAST:
+            case FINGERPRINT_ACQUIRED_VENDOR:
+            case FINGERPRINT_ACQUIRED_START:
+                return true;
+
+            default:
+                return false;
+        }
+    }
 }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index f845024..fec2c46 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -96,7 +96,8 @@
                         Slog.e(getTag(), "Task stack changed for client: " + client);
                         continue;
                     }
-                    if (Utils.isKeyguard(mContext, client.getOwnerString())) {
+                    if (Utils.isKeyguard(mContext, client.getOwnerString())
+                            || Utils.isSystem(mContext, client.getOwnerString())) {
                         continue; // Keyguard is always allowed
                     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index a4a8401..6eb68ca 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -123,7 +123,8 @@
                     Slog.e(TAG, "Task stack changed for client: " + client);
                     return;
                 }
-                if (Utils.isKeyguard(mContext, client.getOwnerString())) {
+                if (Utils.isKeyguard(mContext, client.getOwnerString())
+                        || Utils.isSystem(mContext, client.getOwnerString())) {
                     return; // Keyguard is always allowed
                 }
 
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 23c70ee..2e4200c 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -289,6 +289,8 @@
     private static native void nativeCancelVibrate(long ptr, int deviceId, int token);
     private static native boolean nativeIsVibrating(long ptr, int deviceId);
     private static native int[] nativeGetVibratorIds(long ptr, int deviceId);
+    private static native int nativeGetBatteryCapacity(long ptr, int deviceId);
+    private static native int nativeGetBatteryStatus(long ptr, int deviceId);
     private static native void nativeReloadKeyboardLayouts(long ptr);
     private static native void nativeReloadDeviceAliases(long ptr);
     private static native String nativeDump(long ptr);
@@ -1818,8 +1820,7 @@
     }
 
     private void updateMaximumObscuringOpacityForTouchFromSettings() {
-        final float opacity = InputManager.getInstance().getMaximumObscuringOpacityForTouch(
-                mContext);
+        final float opacity = InputManager.getInstance().getMaximumObscuringOpacityForTouch();
         if (opacity < 0 || opacity > 1) {
             Log.e(TAG, "Invalid maximum obscuring opacity " + opacity
                     + ", it should be >= 0 and <= 1, rejecting update.");
@@ -2009,6 +2010,18 @@
 
     // Binder call
     @Override
+    public int getBatteryStatus(int deviceId) {
+        return nativeGetBatteryStatus(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public int getBatteryCapacity(int deviceId) {
+        return nativeGetBatteryCapacity(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
     public void setPointerIconType(int iconId) {
         nativeSetPointerIconType(mPtr, iconId);
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e32c00f..6843733 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -377,7 +377,8 @@
 
     static final String[] DEFAULT_ALLOWED_ADJUSTMENTS = new String[] {
             Adjustment.KEY_CONTEXTUAL_ACTIONS,
-            Adjustment.KEY_TEXT_REPLIES};
+            Adjustment.KEY_TEXT_REPLIES,
+            Adjustment.KEY_NOT_CONVERSATION};
 
     static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
             RoleManager.ROLE_DIALER,
@@ -2313,6 +2314,13 @@
                     } else if ("false".equals(value)) {
                         mAssistants.disallowAdjustmentType(Adjustment.KEY_RANKING_SCORE);
                     }
+                } else if (SystemUiDeviceConfigFlags.ENABLE_NAS_NOT_CONVERSATION.equals(name)) {
+                    String value = properties.getString(name, null);
+                    if ("true".equals(value)) {
+                        mAssistants.allowAdjustmentType(Adjustment.KEY_NOT_CONVERSATION);
+                    } else if ("false".equals(value)) {
+                        mAssistants.disallowAdjustmentType(Adjustment.KEY_NOT_CONVERSATION);
+                    }
                 }
             }
         };
@@ -9302,21 +9310,30 @@
                 Slog.v(TAG, "onNotificationEnqueuedLocked() called with: r = [" + r + "]");
             }
             final StatusBarNotification sbn = r.getSbn();
-            notifyAssistantLocked(
-                    sbn,
-                    r.getNotificationType(),
-                    true /* sameUserOnly */,
-                    (assistant, sbnHolder) -> {
-                        try {
-                            if (debug) {
-                                Slog.v(TAG,
-                                        "calling onNotificationEnqueuedWithChannel " + sbnHolder);
-                            }
-                            assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel());
-                        } catch (RemoteException ex) {
-                            Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+
+            for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
+                boolean sbnVisible = isVisibleToListener(
+                        sbn, r.getNotificationType(), info)
+                        && info.isSameUser(r.getUserId());
+                if (sbnVisible) {
+                    TrimCache trimCache = new TrimCache(sbn);
+                    final INotificationListener assistant = (INotificationListener) info.service;
+                    final StatusBarNotification sbnToPost = trimCache.ForListener(info);
+                    final StatusBarNotificationHolder sbnHolder =
+                            new StatusBarNotificationHolder(sbnToPost);
+                    try {
+                        if (debug) {
+                            Slog.v(TAG,
+                                    "calling onNotificationEnqueuedWithChannel " + sbnHolder);
                         }
-                    });
+                        final NotificationRankingUpdate update = makeRankingUpdateLocked(info);
+                        assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel(),
+                                update);
+                    } catch (RemoteException ex) {
+                        Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+                    }
+                }
+            }
         }
 
         @GuardedBy("mNotificationLock")
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 2929568..04f399c 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3165,6 +3165,17 @@
             mReadMessages.append("Error reading: " + e.toString());
             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
             Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
+        } finally {
+            if (!mVersion.containsKey(StorageManager.UUID_PRIVATE_INTERNAL)) {
+                Slog.wtf(PackageManagerService.TAG,
+                        "No internal VersionInfo found in settings, using current.");
+                findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
+            }
+            if (!mVersion.containsKey(StorageManager.UUID_PRIMARY_PHYSICAL)) {
+                Slog.wtf(PackageManagerService.TAG,
+                        "No external VersionInfo found in settings, using current.");
+                findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
+            }
         }
 
         // If the build is setup to drop runtime permissions
diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/services/core/java/com/android/server/pm/parsing/PackageParser2.java
index 851ddd1..e8be9b6 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageParser2.java
@@ -19,6 +19,7 @@
 import android.annotation.AnyThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityThread;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageParser;
@@ -33,6 +34,7 @@
 import android.os.Build;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.permission.PermissionManager;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 
@@ -42,6 +44,7 @@
 import com.android.server.pm.parsing.pkg.ParsedPackage;
 
 import java.io.File;
+import java.util.List;
 
 /**
  * The v2 of {@link PackageParser} for use when parsing is initiated in the server and must
@@ -118,10 +121,15 @@
             displayMetrics.setToDefaults();
         }
 
+        PermissionManager permissionManager = ActivityThread.currentApplication()
+                .getSystemService(PermissionManager.class);
+        List<PermissionManager.SplitPermissionInfo> splitPermissions = permissionManager
+                .getSplitPermissions();
+
         mCacher = cacheDir == null ? null : new PackageCacher(cacheDir);
 
         parsingUtils = new ParsingPackageUtils(onlyCoreApps, separateProcesses, displayMetrics,
-                callback);
+                splitPermissions, callback);
 
         ParseInput.Callback enforcementCallback = (changeId, packageName, targetSdkVersion) -> {
             ApplicationInfo appInfo = mSharedAppInfo.get();
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
index 5723e1d..ee30fa2 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
@@ -50,8 +50,6 @@
      */
     private final int mProcessId;
 
-    private boolean mIsForeground;
-
     /**
      * All the clients that share the same resource would be under the same group id.
      *
@@ -90,6 +88,12 @@
     private int mUsingCiCamId = INVALID_RESOURCE_ID;
 
     /**
+     * If the priority is overwritten through
+     * {@link TunerResourceManagerService#setPriority(int, int)}.
+     */
+    private boolean mIsPriorityOverwritten = false;
+
+    /**
      * Optional arbitrary priority value given by the client.
      *
      * <p>This value can override the default priorotiy calculated from
@@ -121,17 +125,10 @@
     }
 
     /**
-     * Set the current isForeground status.
+     * If the client priority is overwrttien.
      */
-    public void setForeground(boolean isForeground) {
-        mIsForeground = isForeground;
-    }
-
-    /**
-     * Get the previous recorded isForeground status.
-     */
-    public boolean isForeground() {
-        return mIsForeground;
+    public boolean isPriorityOverwritten() {
+        return mIsPriorityOverwritten;
     }
 
     public int getGroupId() {
@@ -153,6 +150,17 @@
         mPriority = priority;
     }
 
+    /**
+     * Overwrite the client priority.
+     */
+    public void overwritePriority(int priority) {
+        if (priority < 0) {
+            return;
+        }
+        mIsPriorityOverwritten = true;
+        mPriority = priority;
+    }
+
     public void setNiceValue(int niceValue) {
         mNiceValue = niceValue;
     }
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 988582d..0c04b07 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -507,9 +507,8 @@
                                               .useCase(profile.useCase)
                                               .processId(pid)
                                               .build();
-        clientProfile.setForeground(checkIsForeground(pid));
         clientProfile.setPriority(
-                getClientPriority(profile.useCase, clientProfile.isForeground()));
+                getClientPriority(profile.useCase, checkIsForeground(pid)));
 
         addClientProfile(clientId[0], clientProfile, listener);
     }
@@ -547,8 +546,7 @@
             return false;
         }
 
-        profile.setForeground(checkIsForeground(profile.getProcessId()));
-        profile.setPriority(priority);
+        profile.overwritePriority(priority);
         profile.setNiceValue(niceValue);
 
         return true;
@@ -694,7 +692,7 @@
                 } else if (grantingFrontendHandle == TunerResourceManager.INVALID_RESOURCE_HANDLE) {
                     // Record the frontend id with the lowest client priority among all the
                     // in use frontends when no available frontend has been found.
-                    int priority = getOwnerClientPriority(fr.getOwnerClientId());
+                    int priority = updateAndGetOwnerClientPriority(fr.getOwnerClientId());
                     if (currentLowestPriority > priority) {
                         inUseLowestPriorityFrHandle = fr.getHandle();
                         currentLowestPriority = priority;
@@ -760,7 +758,7 @@
             } else {
                 // Record the lnb id with the lowest client priority among all the
                 // in use lnb when no available lnb has been found.
-                int priority = getOwnerClientPriority(lnb.getOwnerClientId());
+                int priority = updateAndGetOwnerClientPriority(lnb.getOwnerClientId());
                 if (currentLowestPriority > priority) {
                     inUseLowestPriorityLnbHandle = lnb.getHandle();
                     currentLowestPriority = priority;
@@ -818,7 +816,7 @@
         }
         for (int ownerId : cas.getOwnerClientIds()) {
             // Record the client id with lowest priority that is using the current Cas system.
-            int priority = getOwnerClientPriority(ownerId);
+            int priority = updateAndGetOwnerClientPriority(ownerId);
             if (currentLowestPriority > priority) {
                 lowestPriorityOwnerId = ownerId;
                 currentLowestPriority = priority;
@@ -867,7 +865,7 @@
         }
         for (int ownerId : ciCam.getOwnerClientIds()) {
             // Record the client id with lowest priority that is using the current Cas system.
-            int priority = getOwnerClientPriority(ownerId);
+            int priority = updateAndGetOwnerClientPriority(ownerId);
             if (currentLowestPriority > priority) {
                 lowestPriorityOwnerId = ownerId;
                 currentLowestPriority = priority;
@@ -966,18 +964,17 @@
     }
 
     @VisibleForTesting
-    // This mothod is to sync up the request client's foreground/background status and update
-    // the client priority accordingly whenever new resource request comes in.
-    protected void clientPriorityUpdateOnRequest(ClientProfile requestProfile) {
-        int pid = requestProfile.getProcessId();
-        boolean currentIsForeground = checkIsForeground(pid);
-        if (requestProfile.isForeground() == currentIsForeground) {
+    // This mothod is to sync up the request/holder client's foreground/background status and update
+    // the client priority accordingly whenever a new resource request comes in.
+    protected void clientPriorityUpdateOnRequest(ClientProfile profile) {
+        if (profile.isPriorityOverwritten()) {
             // To avoid overriding the priority set through updateClientPriority API.
             return;
         }
-        requestProfile.setForeground(currentIsForeground);
-        requestProfile.setPriority(
-                getClientPriority(requestProfile.getUseCase(), currentIsForeground));
+        int pid = profile.getProcessId();
+        boolean currentIsForeground = checkIsForeground(pid);
+        profile.setPriority(
+                getClientPriority(profile.getUseCase(), currentIsForeground));
     }
 
     @VisibleForTesting
@@ -1154,13 +1151,15 @@
     }
 
     /**
-     * Get the owner client's priority.
+     * Update and get the owner client's priority.
      *
      * @param clientId the owner client id.
      * @return the priority of the owner client.
      */
-    private int getOwnerClientPriority(int clientId) {
-        return getClientProfile(clientId).getPriority();
+    private int updateAndGetOwnerClientPriority(int clientId) {
+        ClientProfile profile = getClientProfile(clientId);
+        clientPriorityUpdateOnRequest(profile);
+        return profile.getPriority();
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 106db0b..058324c 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -180,6 +180,7 @@
         } else if (launchMode == WINDOWING_MODE_FULLSCREEN) {
             if (DEBUG) appendLog("activity-options-fullscreen=" + outParams.mBounds);
         } else if (layout != null && canApplyFreeformPolicy) {
+            mTmpBounds.set(currentParams.mBounds);
             getLayoutBounds(display, root, layout, mTmpBounds);
             if (!mTmpBounds.isEmpty()) {
                 launchMode = WINDOWING_MODE_FREEFORM;
@@ -492,11 +493,11 @@
     }
 
     private void getLayoutBounds(@NonNull DisplayContent display, @NonNull ActivityRecord root,
-            @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect outBounds) {
+            @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect inOutBounds) {
         final int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
         final int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
         if (!windowLayout.hasSpecifiedSize() && verticalGravity == 0 && horizontalGravity == 0) {
-            outBounds.setEmpty();
+            inOutBounds.setEmpty();
             return;
         }
 
@@ -510,11 +511,17 @@
         int width;
         int height;
         if (!windowLayout.hasSpecifiedSize()) {
-            outBounds.setEmpty();
-            getTaskBounds(root, display, windowLayout, WINDOWING_MODE_FREEFORM,
-                    /* hasInitialBounds */ false, outBounds);
-            width = outBounds.width();
-            height = outBounds.height();
+            if (!inOutBounds.isEmpty()) {
+                // If the bounds is resolved already and WindowLayout doesn't have any opinion on
+                // its size, use the already resolved size and apply the gravity to it.
+                width = inOutBounds.width();
+                height = inOutBounds.height();
+            } else {
+                getTaskBounds(root, display, windowLayout, WINDOWING_MODE_FREEFORM,
+                        /* hasInitialBounds */ false, inOutBounds);
+                width = inOutBounds.width();
+                height = inOutBounds.height();
+            }
         } else {
             width = defaultWidth;
             if (windowLayout.width > 0 && windowLayout.width < defaultWidth) {
@@ -555,11 +562,11 @@
                 fractionOfVerticalOffset = 0.5f;
         }
 
-        outBounds.set(0, 0, width, height);
-        outBounds.offset(displayStableBounds.left, displayStableBounds.top);
+        inOutBounds.set(0, 0, width, height);
+        inOutBounds.offset(displayStableBounds.left, displayStableBounds.top);
         final int xOffset = (int) (fractionOfHorizontalOffset * (defaultWidth - width));
         final int yOffset = (int) (fractionOfVerticalOffset * (defaultHeight - height));
-        outBounds.offset(xOffset, yOffset);
+        inOutBounds.offset(xOffset, yOffset);
     }
 
     /**
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 156ef79..31cc295 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -123,7 +123,7 @@
     }
     return -1;
 }
-static bool getAnyPageAdvice(const Vma& vma) {
+static int getAnyPageAdvice(const Vma& vma) {
     if (vma.inode == 0 && !vma.is_shared) {
         return MADV_PAGEOUT;
     }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index dc15b07..5b587e9 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -26,14 +26,14 @@
 // Log debug messages about InputDispatcherPolicy
 #define DEBUG_INPUT_DISPATCHER_POLICY 0
 
-
-#include <atomic>
-#include <cinttypes>
-#include <limits.h>
 #include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
+#include <android/os/IInputConstants.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/Log.h>
+#include <limits.h>
+#include <atomic>
+#include <cinttypes>
 
 #include <utils/Log.h>
 #include <utils/Looper.h>
@@ -46,6 +46,7 @@
 #include <input/SpriteController.h>
 #include <ui/Region.h>
 
+#include <batteryservice/include/batteryservice/BatteryServiceConstants.h>
 #include <inputflinger/InputManager.h>
 
 #include <android_os_MessageQueue.h>
@@ -1908,6 +1909,20 @@
     return vibIdArray;
 }
 
+static jint nativeGetBatteryCapacity(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    std::optional<int32_t> ret = im->getInputManager()->getReader()->getBatteryCapacity(deviceId);
+    return static_cast<jint>(ret.value_or(android::os::IInputConstants::INVALID_BATTERY_CAPACITY));
+}
+
+static jint nativeGetBatteryStatus(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    std::optional<int32_t> ret = im->getInputManager()->getReader()->getBatteryStatus(deviceId);
+    return static_cast<jint>(ret.value_or(BATTERY_STATUS_UNKNOWN));
+}
+
 static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
         jclass /* clazz */, jlong ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -2163,6 +2178,8 @@
         {"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate},
         {"nativeIsVibrating", "(JI)Z", (void*)nativeIsVibrating},
         {"nativeGetVibratorIds", "(JI)[I", (void*)nativeGetVibratorIds},
+        {"nativeGetBatteryCapacity", "(JI)I", (void*)nativeGetBatteryCapacity},
+        {"nativeGetBatteryStatus", "(JI)I", (void*)nativeGetBatteryStatus},
         {"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts},
         {"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases},
         {"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump},
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c3bb757..30f5a34 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -35,10 +35,8 @@
 import static android.app.admin.DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED;
 import static android.app.admin.DevicePolicyManager.CODE_NONSYSTEM_USER_EXISTS;
 import static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER;
-import static android.app.admin.DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT;
 import static android.app.admin.DevicePolicyManager.CODE_OK;
 import static android.app.admin.DevicePolicyManager.CODE_PROVISIONING_NOT_ALLOWED_FOR_NON_DEVELOPER_USERS;
-import static android.app.admin.DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER;
 import static android.app.admin.DevicePolicyManager.CODE_SYSTEM_USER;
 import static android.app.admin.DevicePolicyManager.CODE_USER_HAS_PROFILE_OWNER;
 import static android.app.admin.DevicePolicyManager.CODE_USER_NOT_RUNNING;
@@ -1380,11 +1378,6 @@
             SystemProperties.set(key, value);
         }
 
-        // TODO (b/137101239): clean up split system user codes
-        boolean userManagerIsSplitSystemUser() {
-            return UserManager.isSplitSystemUser();
-        }
-
         boolean userManagerIsHeadlessSystemUserMode() {
             return UserManager.isHeadlessSystemUserMode();
         }
@@ -7404,48 +7397,18 @@
         return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0;
     }
 
+    // TODO (b/137101239): remove this method in follow-up CL
+    // since it's only used for split system user.
     @Override
     public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) {
-        if (!mHasFeature) {
-            return;
-        }
-        Objects.requireNonNull(who, "ComponentName is null");
-        final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallAuthorization(isDeviceOwner(caller));
-
-        // Allow setting this policy to true only if there is a split system user.
-        if (forceEphemeralUsers && !mInjector.userManagerIsSplitSystemUser()) {
-            throw new UnsupportedOperationException(
-                    "Cannot force ephemeral users on systems without split system user.");
-        }
-        boolean removeAllUsers = false;
-        synchronized (getLockObject()) {
-            final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
-            if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) {
-                deviceOwner.forceEphemeralUsers = forceEphemeralUsers;
-                saveSettingsLocked(caller.getUserId());
-                mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers);
-                removeAllUsers = forceEphemeralUsers;
-            }
-        }
-        if (removeAllUsers) {
-            mInjector.binderWithCleanCallingIdentity(() -> mUserManagerInternal.removeAllUsers());
-        }
+        throw new UnsupportedOperationException("This method was used by split system user only.");
     }
 
+    // TODO (b/137101239): remove this method in follow-up CL
+    // since it's only used for split system user.
     @Override
     public boolean getForceEphemeralUsers(ComponentName who) {
-        if (!mHasFeature) {
-            return false;
-        }
-        Objects.requireNonNull(who, "ComponentName is null");
-        final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallAuthorization(isDeviceOwner(caller));
-
-        synchronized (getLockObject()) {
-            final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
-            return deviceOwner.forceEphemeralUsers;
-        }
+        throw new UnsupportedOperationException("This method was used by split system user only.");
     }
 
     @Override
@@ -8631,6 +8594,9 @@
                 return null;
             }
             final ComponentName supervisorComponent = ComponentName.unflattenFromString(supervisor);
+            if (supervisorComponent == null) {
+                return null;
+            }
             if (supervisorComponent.equals(doComponent) || supervisorComponent.equals(
                     poComponent)) {
                 return supervisorComponent;
@@ -12733,13 +12699,6 @@
                 case DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE:
                 case DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE:
                     return checkDeviceOwnerProvisioningPreCondition(callingUserId);
-                // TODO (b/137101239): clean up split system user codes
-                //  ACTION_PROVISION_MANAGED_USER and ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE
-                //  only supported on split-user systems.
-                case DevicePolicyManager.ACTION_PROVISION_MANAGED_USER:
-                    return checkManagedUserProvisioningPreCondition(callingUserId);
-                case DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE:
-                    return checkManagedShareableDeviceProvisioningPreCondition(callingUserId);
             }
         }
         throw new IllegalArgumentException("Unknown provisioning action " + action);
@@ -12775,14 +12734,12 @@
             }
         }
 
-        // TODO (b/137101239): clean up split system user codes
         if (isAdb) {
             // If shell command runs after user setup completed check device status. Otherwise, OK.
             if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
                 // In non-headless system user mode, DO can be setup only if
                 // there's no non-system user
                 if (!mInjector.userManagerIsHeadlessSystemUserMode()
-                        && !mInjector.userManagerIsSplitSystemUser()
                         && mUserManager.getUserCount() > 1) {
                     return CODE_NONSYSTEM_USER_EXISTS;
                 }
@@ -12801,16 +12758,13 @@
             }
             return CODE_OK;
         } else {
-            if (!mInjector.userManagerIsSplitSystemUser()) {
-                // In non-split user mode, DO has to be user 0
-                if (deviceOwnerUserId != UserHandle.USER_SYSTEM) {
-                    return CODE_NOT_SYSTEM_USER;
-                }
-                // Only provision DO before setup wizard completes
-                // TODO (b/171423186): implement deferred DO setup for headless system user mode
-                if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
-                    return CODE_USER_SETUP_COMPLETED;
-                }
+            // DO has to be user 0
+            if (deviceOwnerUserId != UserHandle.USER_SYSTEM) {
+                return CODE_NOT_SYSTEM_USER;
+            }
+            // Only provision DO before setup wizard completes
+            if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
+                return CODE_USER_SETUP_COMPLETED;
             }
             return CODE_OK;
         }
@@ -12831,17 +12785,11 @@
         }
     }
 
-    // TODO (b/137101239): clean up split system user codes
     private int checkManagedProfileProvisioningPreCondition(String packageName,
             @UserIdInt int callingUserId) {
         if (!hasFeatureManagedUsers()) {
             return CODE_MANAGED_USERS_NOT_SUPPORTED;
         }
-        if (callingUserId == UserHandle.USER_SYSTEM
-                && mInjector.userManagerIsSplitSystemUser()) {
-            // Managed-profiles cannot be setup on the system user.
-            return CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER;
-        }
         if (getProfileOwnerAsUser(callingUserId) != null) {
             // Managed user cannot have a managed profile.
             return CODE_USER_HAS_PROFILE_OWNER;
@@ -12917,37 +12865,6 @@
         return null;
     }
 
-    // TODO (b/137101239): clean up split system user codes
-    private int checkManagedUserProvisioningPreCondition(int callingUserId) {
-        if (!hasFeatureManagedUsers()) {
-            return CODE_MANAGED_USERS_NOT_SUPPORTED;
-        }
-        if (!mInjector.userManagerIsSplitSystemUser()) {
-            // ACTION_PROVISION_MANAGED_USER only supported on split-user systems.
-            return CODE_NOT_SYSTEM_USER_SPLIT;
-        }
-        if (callingUserId == UserHandle.USER_SYSTEM) {
-            // System user cannot be a managed user.
-            return CODE_SYSTEM_USER;
-        }
-        if (hasUserSetupCompleted(callingUserId)) {
-            return CODE_USER_SETUP_COMPLETED;
-        }
-        if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) {
-            return CODE_HAS_PAIRED;
-        }
-        return CODE_OK;
-    }
-
-    // TODO (b/137101239): clean up split system user codes
-    private int checkManagedShareableDeviceProvisioningPreCondition(int callingUserId) {
-        if (!mInjector.userManagerIsSplitSystemUser()) {
-            // ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE only supported on split-user systems.
-            return CODE_NOT_SYSTEM_USER_SPLIT;
-        }
-        return checkDeviceOwnerProvisioningPreCondition(callingUserId);
-    }
-
     private boolean hasFeatureManagedUsers() {
         try {
             return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 544eedf..05d6e55 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -359,6 +359,9 @@
             "com.android.server.ConnectivityServiceInitializer";
     private static final String IP_CONNECTIVITY_METRICS_CLASS =
             "com.android.server.connectivity.IpConnectivityMetrics";
+    private static final String MEDIA_COMMUNICATION_SERVICE_CLASS =
+            "com.android.server.media.MediaCommunicationService";
+
     private static final String ROLE_SERVICE_CLASS = "com.android.role.RoleService";
     private static final String GAME_MANAGER_SERVICE_CLASS =
             "com.android.server.graphics.GameManagerService$Lifecycle";
@@ -2528,6 +2531,10 @@
         mSystemServiceManager.startService(APP_SEARCH_MANAGER_SERVICE_CLASS);
         t.traceEnd();
 
+        t.traceBegin("StartMediaCommunicationService");
+        mSystemServiceManager.startService(MEDIA_COMMUNICATION_SERVICE_CLASS);
+        t.traceEnd();
+
         ConcurrentUtils.waitForFutureNoInterrupt(mBlobStoreServiceStart,
                 START_BLOB_STORE_SERVICE);
 
diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
index 743848c..2932926 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
@@ -745,7 +745,8 @@
 
     private InputDevice createInputDeviceWithVibrator(int id) {
         return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0,
-                null, /* hasVibrator= */ true, false, false, false /* hasSensor */);
+                null, /* hasVibrator= */ true, false, false, false /* hasSensor */,
+                false /* hasBattery */);
     }
 
     private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
index bb223b3..fb13d87 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
@@ -55,6 +55,7 @@
 
 import java.io.File;
 import java.io.InputStream;
+import java.util.Collections;
 import java.util.function.Function;
 
 /**
@@ -523,7 +524,7 @@
         int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
 
         ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime(apexFile,
-                flags, false /*collectCertificates*/);
+                flags, Collections.emptyList(), false /*collectCertificates*/);
         if (result.isError()) {
             throw new IllegalStateException(result.getErrorMessage(), result.getException());
         }
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
index d8910de..4dc9a90 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt
@@ -19,12 +19,10 @@
 import android.annotation.RawRes
 import android.content.Context
 import android.content.pm.parsing.ParsingPackage
-import android.content.pm.parsing.ParsingPackageImpl
 import android.content.pm.parsing.ParsingPackageUtils
 import android.content.pm.parsing.result.ParseInput
 import android.content.pm.parsing.result.ParseInput.DeferredError
 import android.content.pm.parsing.result.ParseResult
-import android.content.res.TypedArray
 import android.os.Build
 import androidx.test.InstrumentationRegistry
 import com.android.frameworks.servicestests.R
@@ -130,7 +128,7 @@
                 input.copyTo(output)
             }
         }
-        return ParsingPackageUtils.parseDefaultOneTime(file, 0 /*flags*/,
+        return ParsingPackageUtils.parseDefaultOneTime(file, 0 /*flags*/, emptyList(),
                 false /*collectCertificates*/)
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
index aadab6e..2f36c7f 100644
--- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
@@ -365,13 +365,13 @@
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[0], listener, clientId0);
         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId0[0])
-                .setPriority(clientPriorities[0]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId0[0], clientPriorities[0], 0/*niceValue*/);
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[1], new TestResourcesReclaimListener(), clientId1);
         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId1[0])
-                .setPriority(clientPriorities[1]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId1[0], clientPriorities[1], 0/*niceValue*/);
 
         // Init frontend resources.
         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
@@ -415,13 +415,13 @@
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[0], listener, clientId0);
         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId0[0])
-                .setPriority(clientPriorities[0]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId0[0], clientPriorities[0], 0/*niceValue*/);
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[1], new TestResourcesReclaimListener(), clientId1);
         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId1[0])
-                .setPriority(clientPriorities[1]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId1[0], clientPriorities[1], 0/*niceValue*/);
 
         // Init frontend resources.
         TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
@@ -511,13 +511,13 @@
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[0], listener, clientId0);
         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId0[0])
-                .setPriority(clientPriorities[0]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId0[0], clientPriorities[0], 0/*niceValue*/);
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[1], new TestResourcesReclaimListener(), clientId1);
         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId1[0])
-                .setPriority(clientPriorities[1]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId1[0], clientPriorities[1], 0/*niceValue*/);
 
         // Init cas resources.
         mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
@@ -567,13 +567,13 @@
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[0], listener, clientId0);
         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId0[0])
-                .setPriority(clientPriorities[0]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId0[0], clientPriorities[0], 0/*niceValue*/);
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[1], new TestResourcesReclaimListener(), clientId1);
         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId1[0])
-                .setPriority(clientPriorities[1]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId1[0], clientPriorities[1], 0/*niceValue*/);
 
         // Init cicam/cas resources.
         mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
@@ -697,13 +697,13 @@
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[0], listener, clientId0);
         assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId0[0])
-                .setPriority(clientPriorities[0]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId0[0], clientPriorities[0], 0/*niceValue*/);
         mTunerResourceManagerService.registerClientProfileInternal(
                 profiles[1], new TestResourcesReclaimListener(), clientId1);
         assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
-        mTunerResourceManagerService.getClientProfile(clientId1[0])
-                .setPriority(clientPriorities[1]);
+        mTunerResourceManagerService.updateClientPriorityInternal(
+                clientId1[0], clientPriorities[1], 0/*niceValue*/);
 
         // Init lnb resources.
         int[] lnbHandles = {1};
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
index 28d313b..e71c2f5 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -294,6 +294,8 @@
 
     private InputDevice createInputDevice(int id, boolean hasVibrator) {
         return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0,
-                null, hasVibrator, false, false, false /* hasSensor */);
+                null, hasVibrator, false, false, false /* hasSensor */, false /* hasBattery */);
+
+
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 4984799..ea8619f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -521,6 +521,7 @@
                 WINDOWING_MODE_FULLSCREEN);
     }
 
+
     @Test
     public void testKeepsPictureInPictureLaunchModeInOptions() {
         final TestDisplayContent freeformDisplay = createNewDisplayContent(
@@ -588,11 +589,14 @@
     }
 
     @Test
-    public void testNonEmptyLayoutInfersFreeformWithEmptySize() {
+    public void testLayoutWithGravityAndEmptySizeInfersFreeformAndRespectsCurrentSize() {
         final TestDisplayContent freeformDisplay = createNewDisplayContent(
                 WINDOWING_MODE_FREEFORM);
 
+        final Rect expectedLaunchBounds = new Rect(0, 0, 200, 100);
+
         mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea();
+        mCurrent.mBounds.set(expectedLaunchBounds);
 
         final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
                 .setGravity(Gravity.LEFT).build();
@@ -600,6 +604,9 @@
         assertEquals(RESULT_CONTINUE,
                 new CalculateRequestBuilder().setLayout(layout).calculate());
 
+        assertEquals(expectedLaunchBounds.width(), mResult.mBounds.width());
+        assertEquals(expectedLaunchBounds.height(), mResult.mBounds.height());
+
         assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
                 WINDOWING_MODE_FREEFORM);
     }
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 1a940c7..c6c67fe 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -753,6 +753,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="RenderEffectShaderActivity"
+                  android:label="RenderEffect/Shader"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="com.android.test.hwui.TEST"/>
+            </intent-filter>
+        </activity>
+
         <activity android:name="TextActivity"
              android:label="Text/Simple Text"
              android:theme="@android:style/Theme.NoTitleBar"
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/RenderEffectShaderActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/RenderEffectShaderActivity.java
new file mode 100644
index 0000000..661d48a
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/RenderEffectShaderActivity.java
@@ -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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.RenderEffect;
+import android.graphics.RenderNode;
+import android.graphics.Shader;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.LinearLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class RenderEffectShaderActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        LinearLayout layout = new LinearLayout(this);
+        layout.setClipChildren(false);
+        layout.setGravity(Gravity.CENTER);
+        layout.setOrientation(LinearLayout.VERTICAL);
+
+
+        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(500, 500);
+        params.bottomMargin = 100;
+
+        layout.addView(new ShaderRenderEffectView(this), params);
+
+        setContentView(layout);
+    }
+
+    public static class ShaderRenderEffectView extends View {
+
+        private final Paint mPaint;
+        private final RenderNode mRenderNode;
+
+        public ShaderRenderEffectView(Context c) {
+            super(c);
+
+            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mRenderNode = new RenderNode("blurNode");
+
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+            if (changed) {
+                LinearGradient gradient = new LinearGradient(
+                        0f, 0f,
+                        0f, bottom - top,
+                        new int[]{Color.CYAN, Color.MAGENTA},
+                        null,
+                        Shader.TileMode.CLAMP
+                );
+                mRenderNode.setRenderEffect(
+                        RenderEffect.createShaderEffect(gradient)
+                );
+
+                int width = right - left;
+                int height = bottom - top;
+                mRenderNode.setPosition(0, 0, width, height);
+                Canvas canvas = mRenderNode.beginRecording(width, height);
+                mPaint.setColor(Color.BLUE);
+
+                canvas.drawRect(
+                        0,
+                        0,
+                        width,
+                        height,
+                        mPaint
+                );
+
+                mPaint.setColor(Color.RED);
+                canvas.drawCircle((right - left) / 2f, (bottom - top) / 2f, 50f, mPaint);
+
+                mRenderNode.endRecording();
+            }
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            canvas.drawRenderNode(mRenderNode);
+        }
+    }
+}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 401d87a..8b34755 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -125,21 +125,11 @@
     }
 
     /**
-     * Test rollbacks of staged installs involving only apks with bad update.
-     * Trigger rollback phase.
-     */
-    @Test
-    public void testBadApkOnly_Phase3_Crash() throws Exception {
-        // One more crash to trigger rollback
-        RollbackUtils.sendCrashBroadcast(TestApp.A, 1);
-    }
-
-    /**
      * Test rollbacks of staged installs involving only apks.
      * Confirm rollback phase.
      */
     @Test
-    public void testBadApkOnly_Phase4_VerifyRollback() throws Exception {
+    public void testBadApkOnly_Phase3_VerifyRollback() throws Exception {
         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
         InstallUtils.processUserData(TestApp.A);
 
@@ -447,8 +437,10 @@
                 Rollback.from(TEST_APEX_WITH_APK_V2).to(TEST_APEX_WITH_APK_V1),
                 Rollback.from(TestApp.A, 0).to(TestApp.A1));
 
-        // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
-        RollbackUtils.sendCrashBroadcast(TestApp.A, 5);
+        // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT-1 times
+        RollbackUtils.sendCrashBroadcast(TestApp.A, 4);
+        // Sleep for a while to make sure we don't trigger rollback
+        Thread.sleep(TimeUnit.SECONDS.toMillis(30));
     }
 
     @Test
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 1d5730f..67417bd 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -153,13 +153,14 @@
         getDevice().reboot();
         runPhase("testBadApkOnly_Phase2_VerifyInstall");
 
-        // Trigger rollback and wait for reboot to happen
-        runPhase("testBadApkOnly_Phase3_Crash");
+        // Launch the app to crash to trigger rollback
+        startActivity(TESTAPP_A);
+        // Wait for reboot to happen
         waitForDeviceNotAvailable(2, TimeUnit.MINUTES);
 
         getDevice().waitForDeviceAvailable();
 
-        runPhase("testBadApkOnly_Phase4_VerifyRollback");
+        runPhase("testBadApkOnly_Phase3_VerifyRollback");
 
         assertThat(mLogger).eventOccurred(ROLLBACK_INITIATE, null, REASON_APP_CRASH, TESTAPP_A);
         assertThat(mLogger).eventOccurred(ROLLBACK_BOOT_TRIGGERED, null, null, null);
@@ -304,8 +305,10 @@
         getDevice().reboot();
         // Verify apex was installed and then crash the apk
         runPhase("testRollbackApexWithApkCrashing_Phase2_Crash");
-        // Wait for crash to trigger rollback
-        waitForDeviceNotAvailable(5, TimeUnit.MINUTES);
+        // Launch the app to crash to trigger rollback
+        startActivity(TESTAPP_A);
+        // Wait for reboot to happen
+        waitForDeviceNotAvailable(2, TimeUnit.MINUTES);
         getDevice().waitForDeviceAvailable();
         // Verify rollback occurred due to crash of apk-in-apex
         runPhase("testRollbackApexWithApkCrashing_Phase3_VerifyRollback");
@@ -631,6 +634,12 @@
         }
     }
 
+    private void startActivity(String packageName) throws Exception {
+        String cmd = "am start -S -a android.intent.action.MAIN "
+                + "-c android.intent.category.LAUNCHER " + packageName;
+        getDevice().executeShellCommand(cmd);
+    }
+
     private void crashProcess(String processName, int numberOfCrashes) throws Exception {
         String pid = "";
         String lastPid = "invalid";