Merge "Use IoThread instead of BackgroundThread for HistoricalRegistry." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 6975b55..eac416a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -1243,6 +1243,13 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+java_aconfig_library {
+    name: "android.crashrecovery.flags-aconfig-java-host",
+    aconfig_declarations: "android.crashrecovery.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+    host_supported: true,
+}
+
 // Backup
 java_aconfig_library {
     name: "backup_flags_lib",
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index f21e11a..c7b0be7 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -244,6 +244,10 @@
      * {@link android.app.admin.DevicePolicyManager#isProfileOwnerApp}. You will generally handle
      * this in {@link DeviceAdminReceiver#onProfileProvisioningComplete}.
      *
+     * <p>The intent for this action may include the following extras:
+     * <ul>
+     *     <li>{@link DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}
+     *
      * @see DevicePolicyManager#ACTION_PROVISIONING_SUCCESSFUL
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -801,6 +805,9 @@
      * {@link DevicePolicyManager#ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the same
      * application.
      *
+     * <p>The {@code Intent} may include any of the extras specified for
+     * {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}.
+     *
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
      */
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ba91be9..9058713 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -192,32 +192,134 @@
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
-// TODO(b/172376923) - add CarDevicePolicyManager examples below (or remove reference to it).
 /**
- * Public interface for managing policies enforced on a device. Most clients of this class must be
- * registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device
- * administrator</a>. Additionally, a device administrator may be registered as either a profile or
- * device owner. A given method is accessible to all device administrators unless the documentation
- * for that method specifies that it is restricted to either device or profile owners. Any
- * application calling an api may only pass as an argument a device administrator component it
- * owns. Otherwise, a {@link SecurityException} will be thrown.
+ * Manages device policy and restrictions applied to the user of the device or
+ * apps running on the device.
  *
- * <p><b>Note: </b>on
- * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}, some methods can
- * throw an {@link UnsafeStateException} exception (for example, if the vehicle is moving), so
- * callers running on automotive builds should always check for that exception, otherwise they
- * might crash.
+ * <p>This class contains three types of methods:
+ * <ol><li>Those aimed at <a href="#managingapps">managing apps</a>
+ * <li>Those aimed at the <a href="#roleholder">Device Policy Management Role Holder</a>
+ * <li>Those aimed at <a href="#querying">apps which wish to respect device policy</a>
+ * </ol>
  *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>
- * For more information about managing policies for device administration, read the <a href=
- * "{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a> developer
- * guide. </div>
+ * <p>The intended caller for each API is indicated in its Javadoc.
+ *
+ * <p id="managingapps"><b>Managing Apps</b>
+ * <p>Apps can be made capable of setting device policy ("Managing Apps") either by
+ * being set as a <a href="#deviceadmin">Device Administrator</a>, being set as a
+ * <a href="#devicepolicycontroller">Device Policy Controller</a>, or by holding the
+ * appropriate <a href="#permissions">Permissions</a>.
+ *
+ * <p id="deviceadmin">A <b>Device Administrator</b> is an app which is able to enforce device
+ * policies that it has declared in its device admin XML file. An app can prompt the user to give it
+ * device administator privileges using the {@link #ACTION_ADD_DEVICE_ADMIN} action.
+ *
+ * <p>For more information about Device Administration, read the
+ * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>
+ * developer guide.
+ *
+ * <p id="devicepolicycontroller">Through <a href="#managed_provisioning">Managed Provisioning</a>,
+ * Device Administrator apps can also be recognised as <b>
+ Device Policy Controllers</b>. Device Policy Controllers can be one of
+ * two types:
+ * <ul>
+ * <li>A <i id="deviceowner">Device Owner</i>, which only ever exists on the
+ * {@link UserManager#isSystemUser System User} or {@link UserManager#isMainUser Main User}, is
+ * the most powerful type of Device Policy Controller and can affect policy across the device.
+ * <li>A <i id="profileowner">Profile Owner<i>, which can exist on any user, can
+ * affect policy on the user it is on, and when it is running on
+ * {@link UserManager#isProfile a profile} has
+ * <a href="#profile-on-parent">limited</a> ability to affect policy on its
+ * {@link UserManager#getProfileParent parent}.
+ * </ul>
+ *
+ * <p>Additional capabilities can be provided to Device Policy Controllers in
+ * the following circumstances:
+ * <ul>
+ * <li>A Profile Owner on an <a href="#organization-owned">organization owned</a> device has access
+ * to additional abilities, both <a href="#profile-on-parent-organization-owned">affecting policy on the profile's</a>
+ * {@link UserManager#getProfileParent parent} and also the profile itself.
+ * <li>A Profile Owner running on the {@link UserManager#isSystemUser System User} has access to
+ * additional capabilities which affect the {@link UserManager#isSystemUser System User} and
+ * also the whole device.
+ * <li>A Profile Owner running on an <a href="#affiliated">affiliated</a> user has
+ * capabilities similar to that of a <a href="#deviceowner">Device Owner</a>
+ * </ul>
+ *
+ * <p>For more information, see <a href="{@docRoot}work/dpc/build-dpc">Building a Device Policy
+ * Controller</a>.
+ *
+ * <p><a href="#permissions">Permissions</a> are generally only given to apps
+ * fulfilling particular key roles on the device (such as managing {@link DeviceLockManager
+device locks}).
+ *
+ * <p id="roleholder"><b>Device Policy Management Role Holder</b>
+ * <p>One app on the device fulfills the {@link RoleManager#ROLE_DEVICE_POLICY_MANAGEMENT Device
+Policy Management Role} and is trusted with managing the overall state of
+ * Device Policy. This has access to much more powerful methods than
+ * <a href="#managingapps">managing apps</a>.
+ *
+ * <p id="querying"><b>Querying Device Policy</b>
+ * <p>In most cases, regular apps do not need to concern themselves with device
+ * policy, and restrictions will be enforced automatically. There are some cases
+ * where an app may wish to query device policy to provide a better user
+ * experience. Only a small number of policies allow apps to query them directly.
+ * These APIs will typically have no special required permissions.
+ *
+ * <p id="managedprovisioning"><b>Managed Provisioning</b>
+ * <p>Managed Provisioning is the process of recognising an app as a
+ * <a href="#deviceowner">Device Owner</a> or <a href="#profileowner">Profile Owner</a>. It
+ * involves presenting education and consent screens to the user to ensure they
+ * are aware of the capabilities this grants the <a href="#devicepolicycontroller">Device Policy
+ * Controller</a>
+ *
+ * <p>For more information on provisioning, see <a href="{@docRoot}work/dpc/build-dpc">Building a
+ * Device Policy Controller</a>.
+ *
+ * <p id="managed_profile">A <b>Managed Profile</b> enables data separation. For example to use
+ * a device both for personal and corporate usage. The managed profile and its
+ * {@link UserManager#getProfileParent parent} share a launcher.
+ *
+ * <p id="affiliated"><b>Affiliation</b>
+ * <p>Using the {@link #setAffiliationIds} method, a
+ * <a href="#deviceowner">Device Owner</a> can set a list of affiliation ids for the
+ * {@link UserManager#isSystemUser System User}. Any <a href="#profileowner">Profile Owner</a> on
+ * the same device can also call {@link #setAffiliationIds} to set affiliation ids
+ * for the {@link UserManager user} it is on. When there is the same ID
+ * present in both lists, the user is said to be "affiliated" and we can refer to
+ * the <a href="#profileowner">Profile Owner</a> as a "profile owner on an affiliated
+ * user" or an "affiliated profile owner".
+ *
+ * Becoming affiliated grants the <a href="#profileowner">Profile Owner</a> capabilities similar to
+ * that of the <a href="#deviceowner">Device Owner</a>. It also allows use of the
+ * {@link #bindDeviceAdminServiceAsUser} APIs for direct communication between the
+ * <a href="#deviceowner">Device Owner</a> and
+ * affiliated <a href="#profileowner">Profile Owners</a>.
+ *
+ * <p id="organization-owned"><b>Organization Owned</b></p>
+ * An organization owned device is one which is not owned by the person making use of the device and
+ * is instead owned by an organization such as their employer or education provider. These devices
+ * are recognised as being organization owned either by the presence of a
+ * <a href="#deviceowner">device owner</a> or of a
+ * {@link #isOrganizationOwnedDeviceWithManagedProfile profile which has a profile owner is marked
+ * as organization owned}.
+ *
+ * <p id="profile-on-parent-organization-owned">Profile owners running on an
+ * <a href="organization-owned">organization owned</a> device can exercise additional capabilities
+ * using the {@link #getParentProfileInstance(ComponentName)} API which apply to the parent user.
+ * Each API will indicate if it is usable in this way.
+ *
+ * <p id="automotive"><b>Android Automotive</b>
+ * <p>On {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE
+ * "Android Automotive builds"}, some methods can throw
+ * {@link UnsafeStateException "an exception"} if an action is unsafe (for example, if the vehicle
+ * is moving). Callers running on
+ * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE
+ * "Android Automotive builds"} should always check for this exception.
  */
+
 @SystemService(Context.DEVICE_POLICY_SERVICE)
 @RequiresFeature(PackageManager.FEATURE_DEVICE_ADMIN)
-@SuppressLint("UseIcu")
 public class DevicePolicyManager {
 
     /** @hide */
@@ -257,7 +359,7 @@
      * Fetch the current value of mService.  This is used in the binder cache lambda
      * expressions.
      */
-    private final IDevicePolicyManager getService() {
+    private IDevicePolicyManager getService() {
         return mService;
     }
 
@@ -265,7 +367,7 @@
      * Fetch the current value of mParentInstance.  This is used in the binder cache
      * lambda expressions.
      */
-    private final boolean isParentInstance() {
+    private boolean isParentInstance() {
         return mParentInstance;
     }
 
@@ -273,7 +375,7 @@
      * Fetch the current value of mContext.  This is used in the binder cache lambda
      * expressions.
      */
-    private final Context getContext() {
+    private Context getContext() {
         return mContext;
     }
 
@@ -284,39 +386,80 @@
     }
 
     /**
-     * Activity action: Starts the provisioning flow which sets up a managed profile.
-     *
-     * <p>A managed profile allows data separation for example for the usage of a
-     * device as a personal and corporate device. The user which provisioning is started from and
-     * the managed profile share a launcher.
-     *
-     * <p>This intent will typically be sent by a mobile device management application (MDM).
-     * Provisioning adds a managed profile and sets the MDM as the profile owner who has full
-     * control over the profile.
+     * Activity action: Starts the provisioning flow which sets up a
+     * <a href="#managed-profile">managed profile</a>.
      *
      * <p>It is possible to check if provisioning is allowed or not by querying the method
      * {@link #isProvisioningAllowed(String)}.
      *
-     * <p>In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the
-     * extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
-     * As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra
-     * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only
-     * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported.
+     * <p>The intent may contain the following extras:
      *
-     * <p>The intent may also contain the following extras:
-     * <ul>
-     * <li>{@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE}, optional </li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional, supported from
-     * {@link android.os.Build.VERSION_CODES#N}</li>
-     * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_USER_CONSENT}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_DISCLAIMERS}, optional</li>
-     * </ul>
+     * <table>
+     *  <thead>
+     *      <tr>
+     *          <th>Extra</th>
+     *          <th></th>
+     *          <th>Supported Versions</th>
+     *      </tr>
+     *  </thead>
+     *  <tbody>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE}</td>
+     *          <td colspan="2"></td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}</td>
+     *          <td></td>
+     *          <td>{@link android.os.Build.VERSION_CODES#N}+</td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}</td>
+     *          <td colspan="2"></td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_LOGO_URI}</td>
+     *          <td colspan="2"></td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_SKIP_USER_CONSENT}</td>
+     *          <td colspan="2"><b>Can only be used by an existing device owner trying to create a
+     *          managed profile</b></td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION}</td>
+     *          <td colspan="2"></td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_DISCLAIMERS}</td>
+     *          <td colspan="2"></td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}</td>
+     *          <td>
+     *              <b>Required if {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} is not
+     *              specified. Must match the package name of the calling application.</b>
+     *          </td>
+     *          <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}+</td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</td>
+     *          <td>
+     *              <b>Required if {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is not
+     *              specified. Package name must match the package name of the calling
+     *              application.</b>
+     *          </td>
+     *          <td>{@link android.os.Build.VERSION_CODES#M}+</td>
+     *      </tr>
+     *      <tr>
+     *          <td>{@link #EXTRA_PROVISIONING_ALLOW_OFFLINE}</td>
+     *          <td colspan="2">On {@link android.os.Build.VERSION_CODES#TIRAMISU}+, when set to
+     *          true this will <b>force</b> offline provisioning instead of allowing it</td>
+     *      </tr>
+     *  </tbody>
+     * </table>
      *
-     * <p>When managed provisioning has completed, broadcasts are sent to the application specified
-     * in the provisioning intent. The
+     * <p>When <a href="#managedprovisioning">managed provisioning</a> has completed, broadcasts
+     * are sent to the application specified in the provisioning intent. The
      * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} broadcast is sent in the
      * managed profile and the {@link #ACTION_MANAGED_PROFILE_PROVISIONED} broadcast is sent in
      * the primary profile.
@@ -325,25 +468,25 @@
      * completed, along with the above broadcast, activity intent
      * {@link #ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the profile owner.
      *
-     * <p>If provisioning fails, the managedProfile is removed so the device returns to its
+     * <p>If provisioning fails, the managed profile is removed so the device returns to its
      * previous state.
      *
      * <p>If launched with {@link android.app.Activity#startActivityForResult(Intent, int)} a
-     * result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part of
+     * result code of {@link android.app.Activity#RESULT_OK} indicates 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.
+     * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} indicates
+     * that the user backed-out of provisioning or some precondition for provisioning wasn't met.
      *
-     * <p>If a device policy management role holder (DPMRH) updater is present on the device, an
-     * internet connection attempt must be made prior to launching this intent. If internet
-     * connection could not be established, provisioning will fail unless {@link
+     * <p>If a <a href="#roleholder">device policy management role holder</a> updater is present on
+     * the device, an internet connection attempt must be made prior to launching this intent. If
+     * an internet connection can not be established, provisioning will fail unless {@link
      * #EXTRA_PROVISIONING_ALLOW_OFFLINE} is explicitly set to {@code true}, in which case
-     * provisioning will continue without using the DPMRH. If an internet connection has been
-     * established, the DPMRH updater will be launched, which will update the DPMRH if it's not
-     * present on the device, or if it's present and not valid.
-     *
-     * <p>If a DPMRH is present on the device and valid, the provisioning flow will be deferred to
-     * it.
+     * provisioning will continue without using the
+     * <a href="#roleholder">device policy management role holder</a>. If an internet connection
+     * has been established, the <a href="#roleholder">device policy management role holder</a>
+     * updater will be launched, which may update the
+     * <a href="#roleholder">device policy management role holder</a> before continuing
+     * provisioning.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_PROVISION_MANAGED_PROFILE
@@ -822,31 +965,25 @@
             "android.app.extra.FORCE_UPDATE_ROLE_HOLDER";
 
     /**
-     * A boolean extra indicating whether offline provisioning is allowed.
-     *
-     * <p>For the online provisioning flow, there will be an attempt to download and install
-     * the latest version of the device policy management role holder. The platform will then
-     * delegate provisioning to the device policy management role holder via role holder-specific
-     * provisioning actions.
-     *
-     * <p>For the offline provisioning flow, the provisioning flow will always be handled by
-     * the platform.
-     *
-     * <p>If this extra is set to {@code false}, the provisioning flow will enforce that an
-     * internet connection is established, which will start the online provisioning flow. If an
-     * internet connection cannot be established, provisioning will fail.
-     *
-     * <p>If this extra is set to {@code true}, the provisioning flow will still try to connect to
-     * the internet, but if it fails it will start the offline provisioning flow.
-     *
-     * <p>For T if this extra is set to {@code true}, the provisioning flow will be forced through
-     * the platform and there will be no attempt to download and install the device policy
-     * management role holder.
+     * A boolean extra indicating whether offline provisioning should be used.
      *
      * <p>The default value is {@code false}.
      *
-     * <p>This extra is respected when provided via the provisioning intent actions such as {@link
-     * #ACTION_PROVISION_MANAGED_PROFILE}.
+     * <p>Usually during the <a href="#managedprovisioning">provisioning flow</a>, there will be
+     * an attempt to download and install the latest version of the <a href="#roleholder">device
+     * policy management role holder</a>. The platform will then
+     * delegate provisioning to the <a href="#roleholder">device
+     *      * policy management role holder</a>.
+     *
+     * <p>When this extra is set to {@code true}, the
+     * <a href="#managedprovisioning">provisioning flow</a> will always be handled by the platform
+     * and the <a href="#roleholder">device policy management role holder</a>'s part skipped.
+     *
+     * <p>On Android versions prior to {@link Build.VERSION_CODES#TIRAMISU}, when this extra is
+     * {@code false}, the <a href="#managedprovisioning">provisioning flow</a> will enforce that an
+     * internet connection is established, or otherwise fail. When this extra is {@code true}, a
+     * connection will still be attempted but when it cannot be established provisioning will
+     * continue offline.
      */
     public static final String EXTRA_PROVISIONING_ALLOW_OFFLINE =
             "android.app.extra.PROVISIONING_ALLOW_OFFLINE";
@@ -1057,64 +1194,40 @@
     public static final long DEFAULT_STRONG_AUTH_TIMEOUT_MS = 72 * 60 * 60 * 1000; // 72h
 
     /**
-     * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
-     * allows a mobile device management application or NFC programmer application which starts
-     * managed provisioning to pass data to the management application instance after provisioning.
+     * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that is
+     * passed directly to the <a href="#devicepolicycontroller">Device Policy Controller</a>
+     * after <a href="#managed-provisioning">provisioning</a>.
+     *
      * <p>
-     * If used with {@link #ACTION_PROVISION_MANAGED_PROFILE} it can be used by the application that
-     * sends the intent to pass data to itself on the newly created profile.
-     * If used with {@link #ACTION_PROVISION_MANAGED_DEVICE} it allows passing data to the same
-     * instance of the app on the primary user.
      * Starting from {@link android.os.Build.VERSION_CODES#M}, if used with
      * {@link #MIME_TYPE_PROVISIONING_NFC} as part of NFC managed device provisioning, the NFC
      * message should contain a stringified {@link java.util.Properties} instance, whose string
      * properties will be converted into a {@link android.os.PersistableBundle} and passed to the
      * management application after provisioning.
-     *
-     * <p>Admin apps will receive this extra in their {@link #ACTION_GET_PROVISIONING_MODE} and
-     * {@link #ACTION_ADMIN_POLICY_COMPLIANCE} intent handlers. Additionally, {@link
-     * #ACTION_GET_PROVISIONING_MODE} may also return this extra which will then be sent over to
-     * {@link #ACTION_ADMIN_POLICY_COMPLIANCE}, alongside the original values that were passed to
-     * {@link #ACTION_GET_PROVISIONING_MODE}.
-     *
-     * <p>
-     * In both cases the application receives the data in
-     * {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with the action
-     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. The bundle is not changed
-     * during the managed provisioning.
      */
     public static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE =
             "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
 
     /**
-     * A String extra holding the package name of the mobile device management application that
-     * will be set as the profile owner or device owner.
+     * A String extra holding the package name of the application that
+     * will be set as <a href="#devicepolicycontroller">Device Policy Controller</a>.
      *
-     * <p>If an application starts provisioning directly via an intent with action
-     * {@link #ACTION_PROVISION_MANAGED_PROFILE} this package has to match the package name of the
-     * application that started provisioning. The package will be set as profile owner in that case.
+     * <p>When this extra is set, the application must have exactly one
+     * {@link DeviceAdminReceiver device admin receiver}. This receiver will be set as the
+     * <a href="#devicepolicycontroller">Device Policy Controller</a>.
      *
-     * <p>This package is set as device owner when device owner provisioning is started by an NFC
-     * message containing an NFC record with MIME type {@link #MIME_TYPE_PROVISIONING_NFC}.
-     *
-     * <p> When this extra is set, the application must have exactly one device admin receiver.
-     * This receiver will be set as the profile or device owner and active admin.
-     *
-     * @see DeviceAdminReceiver
-     * @deprecated Use {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}. This extra is still
-     * supported, but only if there is only one device admin receiver in the package that requires
-     * the permission {@link android.Manifest.permission#BIND_DEVICE_ADMIN}.
+     * @deprecated Use {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}.
      */
     @Deprecated
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
 
     /**
-     * A ComponentName extra indicating the device admin receiver of the mobile device management
-     * application that will be set as the profile owner or device owner and active admin.
+     * A ComponentName extra indicating the {@link DeviceAdminReceiver device admin receiver} of
+     * the application that will be set as the <a href="#devicepolicycontroller">
+     *     Device Policy Controller</a>.
      *
      * <p>If an application starts provisioning directly via an intent with action
-     * {@link #ACTION_PROVISION_MANAGED_PROFILE} or
      * {@link #ACTION_PROVISION_MANAGED_DEVICE} the package name of this
      * component has to match the package name of the application that started provisioning.
      *
@@ -1123,35 +1236,28 @@
      * message containing an NFC record with MIME type
      * {@link #MIME_TYPE_PROVISIONING_NFC}. For the NFC record, the component name must be
      * flattened to a string, via {@link ComponentName#flattenToShortString()}.
-     *
-     * @see DeviceAdminReceiver
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME
         = "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME";
 
     /**
      * An {@link android.accounts.Account} extra holding the account to migrate during managed
-     * profile provisioning. If the account supplied is present in the primary user, it will be
-     * copied, along with its credentials to the managed profile and removed from the primary user.
+     * profile provisioning.
      *
-     * Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}, with managed account provisioning, or
-     * return as an extra to the intent result from the {@link #ACTION_GET_PROVISIONING_MODE}
-     * activity.
+     * <p>If the account supplied is present in the user, it will be copied, along with its
+     * credentials to the managed profile and removed from the user.
      */
-
     public static final String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE
         = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
 
     /**
-     * Boolean extra to indicate that the migrated account should be kept. This is used in
-     * conjunction with {@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE}. If it's set to {@code true},
-     * the account will not be removed from the primary user after it is migrated to the newly
-     * created user or profile.
+     * Boolean extra to indicate that the
+     * {@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE migrated account} should be kept.
      *
-     * <p> Defaults to {@code false}
+     * <p>If it's set to {@code true}, the account will not be removed from the user after it is
+     * migrated to the newly created user or profile.
      *
-     * <p> Use with {@link #ACTION_PROVISION_MANAGED_PROFILE} or set as an extra to the
-     * intent result of the {@link #ACTION_GET_PROVISIONING_MODE} activity.
+     * <p>Defaults to {@code false}
      *
      * @see #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE
      */
@@ -1590,17 +1696,14 @@
             "android.app.action.PROVISIONING_SUCCESSFUL";
 
     /**
-     * A boolean extra indicating whether device encryption can be skipped as part of device owner
-     * or managed profile provisioning.
+     * A boolean extra indicating whether device encryption can be skipped as part of
+     * <a href="#managed-provisioning>provisioning</a>.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} or an intent with action
      * {@link #ACTION_PROVISION_MANAGED_DEVICE} that starts device owner provisioning.
      *
      * <p>From {@link android.os.Build.VERSION_CODES#N} onwards, this is also supported for an
      * intent with action {@link #ACTION_PROVISION_MANAGED_PROFILE}.
-     *
-     * <p>This extra can also be returned by the admin app when performing the admin-integrated
-     * provisioning flow as a result of the {@link #ACTION_GET_PROVISIONING_MODE} activity.
      */
     public static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION =
              "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
@@ -1608,23 +1711,22 @@
     /**
      * A {@link Uri} extra pointing to a logo image. This image will be shown during the
      * provisioning. If this extra is not passed, a default image will be shown.
-     * <h5>The following URI schemes are accepted:</h5>
+     *
+     * <p><b>The following URI schemes are accepted:</b>
      * <ul>
      * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
      * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
      * </ul>
      *
-     * <p> It is the responsibility of the caller to provide an image with a reasonable
+     * <p>It is the responsibility of the caller to provide an image with a reasonable
      * pixel density for the device.
      *
-     * <p> If a content: URI is passed, the intent should have the flag
+     * <p>If a content: URI is passed, the intent should also have the flag
      * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and the uri should be added to the
-     * {@link android.content.ClipData} of the intent too.
+     * {@link android.content.ClipData} of the intent.
      *
-     * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_PROFILE} or
-     * {@link #ACTION_PROVISION_MANAGED_DEVICE}
-     *
-     * @deprecated Logo customization is no longer supported in the provisioning flow.
+     * @deprecated Logo customization is no longer supported in the
+     *             <a href="#managedprovisioning">provisioning flow</a>.
      */
     @Deprecated
     public static final String EXTRA_PROVISIONING_LOGO_URI =
@@ -1632,7 +1734,8 @@
 
     /**
      * A {@link Bundle}[] extra consisting of list of disclaimer headers and disclaimer contents.
-     * Each {@link Bundle} must have both {@link #EXTRA_PROVISIONING_DISCLAIMER_HEADER}
+     *
+     * <p>Each {@link Bundle} must have both {@link #EXTRA_PROVISIONING_DISCLAIMER_HEADER}
      * as disclaimer header, and {@link #EXTRA_PROVISIONING_DISCLAIMER_CONTENT} as disclaimer
      * content.
      *
@@ -1653,20 +1756,21 @@
     /**
      * A String extra of localized disclaimer header.
      *
-     * <p> The extra is typically the company name of mobile device management application (MDM)
+     * <p>The extra is typically the company name of mobile device management application (MDM)
      * or the organization name.
      *
-     * <p> Use in Bundle {@link #EXTRA_PROVISIONING_DISCLAIMERS}
+     * <p>{@link ApplicationInfo#FLAG_SYSTEM System apps} can also insert a disclaimer by declaring
+     * an application-level meta-data in {@code AndroidManifest.xml}.
      *
-     * <p> System app, i.e. application with {@link ApplicationInfo#FLAG_SYSTEM}, can also insert a
-     * disclaimer by declaring an application-level meta-data in {@code AndroidManifest.xml}.
-     * Must use it with {@link #EXTRA_PROVISIONING_DISCLAIMER_CONTENT}. Here is the example:
-     *
+     * <p>For example:
      * <pre>
      *  &lt;meta-data
      *      android:name="android.app.extra.PROVISIONING_DISCLAIMER_HEADER"
      *      android:resource="@string/disclaimer_header"
      * /&gt;</pre>
+     *
+     * <p>This must be accompanied with another extra using the key
+     * {@link #EXTRA_PROVISIONING_DISCLAIMER_CONTENT}.
      */
     public static final String EXTRA_PROVISIONING_DISCLAIMER_HEADER =
             "android.app.extra.PROVISIONING_DISCLAIMER_HEADER";
@@ -1680,35 +1784,35 @@
      * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
      * </ul>
      *
-     * <p> Styled text is supported in the disclaimer content. The content is parsed by
-     * {@link android.text.Html#fromHtml(String)} and displayed in a
-     * {@link android.widget.TextView}.
+     * <p>Styled text is supported. This is parsed by {@link android.text.Html#fromHtml(String)}
+     * and displayed in a {@link android.widget.TextView}.
      *
-     * <p> If a <code>content:</code> URI is passed, URI is passed, the intent should have the flag
-     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and the uri should be added to the
-     * {@link android.content.ClipData} of the intent too.
+     * <p>If a <code>content:</code> URI is passed, the intent should also have the
+     * flag {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and the uri should be added to the
+     * {@link android.content.ClipData} of the intent.
      *
-     * <p> Use in Bundle {@link #EXTRA_PROVISIONING_DISCLAIMERS}
-     *
-     * <p> System app, i.e. application with {@link ApplicationInfo#FLAG_SYSTEM}, can also insert a
+     * <p>{@link ApplicationInfo#FLAG_SYSTEM System apps} can also insert a
      * disclaimer by declaring an application-level meta-data in {@code AndroidManifest.xml}.
-     * Must use it with {@link #EXTRA_PROVISIONING_DISCLAIMER_HEADER}. Here is the example:
+     *
+     * <p>For example:
      *
      * <pre>
      *  &lt;meta-data
      *      android:name="android.app.extra.PROVISIONING_DISCLAIMER_CONTENT"
      *      android:resource="@string/disclaimer_content"
      * /&gt;</pre>
+     *
+     * <p>This must be accompanied with another extra using the key
+     * {@link #EXTRA_PROVISIONING_DISCLAIMER_HEADER}.
      */
     public static final String EXTRA_PROVISIONING_DISCLAIMER_CONTENT =
             "android.app.extra.PROVISIONING_DISCLAIMER_CONTENT";
 
     /**
-     * A boolean extra indicating if the user consent steps from the provisioning flow should be
-     * skipped. If unspecified, defaults to {@code false}.
+     * A boolean extra indicating if the user consent steps from the
+     * <a href="#managed-provisioning">provisioning flow</a> should be skipped.
      *
-     * It can only be used by an existing device owner trying to create a managed profile via
-     * {@link #ACTION_PROVISION_MANAGED_PROFILE}. Otherwise it is ignored.
+     * <p>If unspecified, defaults to {@code false}.
      *
      * @deprecated this extra is no longer relevant as device owners cannot create managed profiles
      */
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index 17d1404..7dc151d 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -288,7 +288,7 @@
         if (bitmap == null) {
             throw new IllegalArgumentException("bitmap must not be null");
         }
-        validateHotSpot(bitmap, hotSpotX, hotSpotY);
+        validateHotSpot(bitmap, hotSpotX, hotSpotY, false /* isScaled */);
 
         PointerIcon icon = new PointerIcon(TYPE_CUSTOM);
         icon.mBitmap = bitmap;
@@ -521,7 +521,9 @@
 
         BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
         final Bitmap bitmap = getBitmapFromDrawable(bitmapDrawable);
-        validateHotSpot(bitmap, hotSpotX, hotSpotY);
+        // The bitmap and hotspot are loaded from the context, which means it is implicitly scaled
+        // to the current display density, so treat this as a scaled icon when verifying hotspot.
+        validateHotSpot(bitmap, hotSpotX, hotSpotY, true /* isScaled */);
         // Set the properties now that we have successfully loaded the icon.
         mBitmap = bitmap;
         mHotSpotX = hotSpotX;
@@ -535,11 +537,16 @@
                 + ", hotspotX=" + mHotSpotX + ", hotspotY=" + mHotSpotY + "}";
     }
 
-    private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY) {
-        if (hotSpotX < 0 || hotSpotX >= bitmap.getWidth()) {
+    private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY,
+            boolean isScaled) {
+        // Be more lenient when checking the hotspot for scaled icons to account for the restriction
+        // that bitmaps must have an integer size.
+        if (hotSpotX < 0 || (isScaled ? (int) hotSpotX > bitmap.getWidth()
+                : hotSpotX >= bitmap.getWidth())) {
             throw new IllegalArgumentException("x hotspot lies outside of the bitmap area");
         }
-        if (hotSpotY < 0 || hotSpotY >= bitmap.getHeight()) {
+        if (hotSpotY < 0 || (isScaled ? (int) hotSpotY > bitmap.getHeight()
+                : hotSpotY >= bitmap.getHeight())) {
             throw new IllegalArgumentException("y hotspot lies outside of the bitmap area");
         }
     }
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index e531bcb..06ae11fee 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -135,7 +135,7 @@
             DialogStatus.SHOWN,
     })
     /** Denotes the user shortcut type. */
-    @interface DialogStatus {
+    public @interface DialogStatus {
         int NOT_SHOWN = 0;
         int SHOWN  = 1;
     }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2115f64..a622d36 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -7015,4 +7015,9 @@
     <!-- Frame rate compatibility value for Wallpaper
          FRAME_RATE_COMPATIBILITY_MIN (102) is used by default for lower power consumption -->
     <integer name="config_wallpaperFrameRateCompatibility">102</integer>
+
+    <!-- Min time in milliseconds to complete an emergency gesture for it count.
+         If the gesture is completed faster than this, we assume it's not performed by human and the
+         event gets ignored. -->
+    <integer name="config_defaultMinEmergencyGestureTapDurationMillis">200</integer>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9e09540..eccd7bf 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5401,4 +5401,6 @@
 
   <!-- Frame rate compatibility value for Wallpaper -->
   <java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" />
+
+  <java-symbol type="integer" name="config_defaultMinEmergencyGestureTapDurationMillis" />
 </resources>
diff --git a/packages/CredentialManager/wear/res/drawable/passkey_icon.xml b/packages/CredentialManager/wear/res/drawable/passkey_icon.xml
deleted file mode 100644
index be366bf..0000000
--- a/packages/CredentialManager/wear/res/drawable/passkey_icon.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-    <path
-        android:pathData="M23,10.5H17V13.5H23V10.5Z"
-        android:fillColor="#188038"/>
-    <path
-        android:pathData="M6.5,17.5C3.5,17.5 1,15 1,12C1,9 3.5,6.5 6.5,6.5C9.5,6.5 12,9 12,12C12,15 9.5,17.5 6.5,17.5ZM6.5,9.5C5.1,9.5 4,10.6 4,12C4,13.4 5.1,14.5 6.5,14.5C7.9,14.5 9,13.4 9,12C9,10.6 7.9,9.5 6.5,9.5Z"
-        android:fillColor="#4285F4"/>
-    <path
-        android:pathData="M21,13.5H19H17V16.5H19V15.5C19,14.9 19.4,14.5 20,14.5C20.6,14.5 21,14.9 21,15.5V16.5H23V13.5H21Z"
-        android:fillColor="#34A853"/>
-    <path
-        android:pathData="M11.8,10.5H8.5C8.8,10.9 9,11.4 9,12C9,12.6 8.8,13.1 8.5,13.5H11.8C11.9,13 12,12.5 12,12C12,11.5 11.9,11 11.8,10.5Z"
-        android:fillColor="#EA4335"/>
-    <path
-        android:pathData="M17,10.5H11.8C11.9,11 12,11.5 12,12C12,12.5 11.9,13 11.8,13.5H17V10.5Z"
-        android:fillColor="#FBBC04"/>
-</vector>
diff --git a/packages/CredentialManager/wear/res/values-watch/donottranslate.xml b/packages/CredentialManager/wear/res/values-watch/donottranslate.xml
new file mode 100644
index 0000000..c3ab3cb
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-watch/donottranslate.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- font-family-device-default is expected to be preloaded in the font_customization.xml(/vendor/<OEM>/products/<PRODUCT>/fonts/fonts_customization.xml)-->
+    <!-- Falls back to system default when font-family-device-default doesn't exist    -->
+    <string name="wear_material_compose_display_1_font_family">font-family-device-default</string>
+    <string name="wear_material_compose_display_2_font_family">font-family-device-default</string>
+    <string name="wear_material_compose_display_3_font_family">font-family-device-default</string>
+    <string name="wear_material_compose_title_1_font_family">font-family-medium-device-default</string>
+    <string name="wear_material_compose_title_2_font_family">font-family-medium-device-default</string>
+    <string name="wear_material_compose_title_3_font_family">font-family-device-default</string>
+    <string name="wear_material_compose_body_1_font_family">font-family-text-device-default</string>
+    <string name="wear_material_compose_body_2_font_family">font-family-text-device-default</string>
+    <string name="wear_material_compose_button_font_family">font-family-text-medium-device-default</string>
+    <string name="wear_material_compose_caption_1_font_family">font-family-text-medium-device-default</string>
+    <string name="wear_material_compose_caption_2_font_family">font-family-text-medium-device-default</string>
+    <string name="wear_material_compose_caption_3_font_family">font-family-text-medium-device-default</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values/colors.xml b/packages/CredentialManager/wear/res/values/colors.xml
deleted file mode 100644
index bf10bb3..0000000
--- a/packages/CredentialManager/wear/res/values/colors.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2024 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<resources>
-    <color name="wear_material_almond">#FFFCF7EB</color>
-    <color name="wear_material_almond_dark">#FF262523</color>
-</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/res/values/overlayable.xml b/packages/CredentialManager/wear/res/values/overlayable.xml
new file mode 100644
index 0000000..5b9d372
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values/overlayable.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <overlayable name="CredentialSelectorStyles">
+        <policy type="product|system|vendor|odm|oem">
+            <!--START WEAR SPECIFIC FONT STRINGS -->
+            <item type="string" name="wear_material_compose_display_1_font_family" />
+            <item type="string" name="wear_material_compose_display_2_font_family" />
+            <item type="string" name="wear_material_compose_display_3_font_family" />
+            <item type="string" name="wear_material_compose_title_1_font_family" />
+            <item type="string" name="wear_material_compose_title_2_font_family" />
+            <item type="string" name="wear_material_compose_title_3_font_family" />
+            <item type="string" name="wear_material_compose_body_1_font_family" />
+            <item type="string" name="wear_material_compose_body_2_font_family" />
+            <item type="string" name="wear_material_compose_button_font_family" />
+            <item type="string" name="wear_material_compose_caption_1_font_family" />
+            <item type="string" name="wear_material_compose_caption_2_font_family" />
+            <item type="string" name="wear_material_compose_caption_3_font_family" />
+            <!--END WEAR SPECIFIC FONT STRINGS -->
+
+        </policy>
+
+    </overlayable>
+
+</resources>
diff --git a/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt b/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt
index 3422d3d..6c14563 100644
--- a/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt
+++ b/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt
@@ -65,29 +65,29 @@
             isLastUnlocked = true
         )
 
-    val passkeyCredentialEntryInfo =
+    private val passkeyCredentialEntryInfo =
         createCredentialEntryInfo(credentialType = CredentialType.PASSKEY, userName = "userName")
 
-    val unknownCredentialEntryInfo =
+    private val unknownCredentialEntryInfo =
         createCredentialEntryInfo(credentialType = CredentialType.UNKNOWN, userName = "userName2")
 
-    val passwordCredentialEntryInfo =
+    private val passwordCredentialEntryInfo =
         createCredentialEntryInfo(credentialType = CredentialType.PASSWORD, userName = "userName")
 
-    val recentlyUsedPasskeyCredential =
+    private val recentlyUsedPasskeyCredential =
         createCredentialEntryInfo(credentialType =
     CredentialType.PASSKEY, lastUsedTimeMillis = 2L, userName = "userName")
 
-    val recentlyUsedPasswordCredential =
+    private val recentlyUsedPasswordCredential =
         createCredentialEntryInfo(credentialType =
     CredentialType.PASSWORD, lastUsedTimeMillis = 2L, userName = "userName")
 
-    val credentialList1 = listOf(
+    private val credentialList1 = listOf(
         passkeyCredentialEntryInfo,
         passwordCredentialEntryInfo
     )
 
-    val credentialList2 = listOf(
+    private val credentialList2 = listOf(
         passkeyCredentialEntryInfo,
         passwordCredentialEntryInfo,
         recentlyUsedPasskeyCredential,
@@ -118,11 +118,12 @@
                 unknownCredentialEntryInfo)))).toGet(isPrimary = true)
 
         assertThat(getCredentialUiState).isEqualTo(
-            CredentialSelectorUiState.Get.SingleEntryPerAccount(
+            CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen(
                 sortedEntries = listOf(
                     passkeyCredentialEntryInfo, // userName
                     unknownCredentialEntryInfo // userName2
                 ),
+                icon = mDrawable,
                 authenticationEntryList = listOf(authenticationEntryInfo)
             )) // prefer passkey from account 1, then unknown from account 2
     }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index 0fe35e6..652e62c 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -21,7 +21,7 @@
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
 import androidx.activity.viewModels
-import androidx.wear.compose.material.MaterialTheme
+import com.android.credentialmanager.ui.theme.WearCredentialSelectorTheme
 import com.android.credentialmanager.ui.WearApp
 import com.google.android.horologist.annotations.ExperimentalHorologistApi
 import dagger.hilt.android.AndroidEntryPoint
@@ -36,7 +36,7 @@
         super.onCreate(savedInstanceState)
         setTheme(android.R.style.Theme_DeviceDefault)
         setContent {
-            MaterialTheme {
+            WearCredentialSelectorTheme {
                 WearApp(
                     flowEngine = viewModel,
                     onCloseApp = { finish() },
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index b7fa33e..3608568 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -86,7 +86,7 @@
         when (uiState.value) {
             is Get.MultipleEntry -> isPrimaryScreen.value = true
             is Create, Close, is Cancel, Idle -> shouldClose.value = true
-            is Get.SingleEntry, is Get.SingleEntryPerAccount -> cancel()
+            is Get.SingleEntry, is Get.MultipleEntryPrimaryScreen -> cancel()
         }
     }
 
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
index c05fc93..b2f55c1 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
@@ -17,6 +17,7 @@
 package com.android.credentialmanager
 
 import android.content.Intent
+import android.graphics.drawable.Drawable
 import androidx.activity.result.IntentSenderRequest
 import androidx.compose.runtime.Composable
 import com.android.credentialmanager.model.EntryInfo
@@ -71,14 +72,14 @@
         /** Getting credential UI state when there is only one credential available. */
         data class SingleEntry(val entry: CredentialEntryInfo) : Get()
         /**
-         * Getting credential UI state when there is only one account while with multiple
-         * credentials, with different types(eg, passkey vs password) or providers.
+         * Getting credential UI state on primary screen when there is are multiple accounts.
          */
-        data class SingleEntryPerAccount(
+        data class MultipleEntryPrimaryScreen(
+            val icon: Drawable?,
             val sortedEntries: List<CredentialEntryInfo>,
             val authenticationEntryList: List<AuthenticationEntryInfo>,
             ) : Get()
-        /** Getting credential UI state when there are multiple accounts available. */
+        /** Getting credential UI state on secondary screen when there are multiple accounts available. */
         data class MultipleEntry(
             val accounts: List<PerUserNameEntries>,
             val actionEntryList: List<ActionEntryInfo>,
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
index 018db68..d67c8c2 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
@@ -29,7 +29,7 @@
 import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
 import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState
 import com.android.credentialmanager.CredentialSelectorUiState
-import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntryPerAccount
+import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen
 import com.android.credentialmanager.CredentialSelectorUiState.Get.SingleEntry
 import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry
 import com.android.credentialmanager.FlowEngine
@@ -95,7 +95,7 @@
 
         scrollable(Screen.MultipleCredentialsScreenFold.route) {
             MultiCredentialsFoldScreen(
-                credentialSelectorUiState = (remember { uiState } as SingleEntryPerAccount),
+                credentialSelectorUiState = (remember { uiState } as MultipleEntryPrimaryScreen),
                 columnState = it.columnState,
                 flowEngine = flowEngine,
             )
@@ -169,7 +169,7 @@
             }
         }
 
-            is SingleEntryPerAccount -> {
+            is MultipleEntryPrimaryScreen -> {
                 navController.navigateToMultipleCredentialsFoldScreen()
             }
 
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt
index 18c9f31..c641d7f 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt
@@ -32,7 +32,6 @@
 import androidx.wear.compose.material.ChipColors
 import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.text.style.TextAlign
 import androidx.wear.compose.material.ChipDefaults
 import com.android.credentialmanager.R
@@ -80,8 +79,7 @@
     icon: Drawable? = null,
     isAuthenticationEntryLocked: Boolean = false,
     modifier: Modifier = Modifier,
-    colors: ChipColors =
-        ChipDefaults.chipColors(backgroundColor = colorResource(R.color.wear_material_almond)),
+    colors: ChipColors = ChipDefaults.primaryChipColors(),
     ) {
     val labelParam: (@Composable RowScope.() -> Unit) =
         {
@@ -168,11 +166,9 @@
             WearButtonText(
                 text = stringResource(R.string.dialog_continue_button),
                 textAlign = TextAlign.Center,
-                color = colorResource(R.color.wear_material_almond_dark),
             )
         },
-        colors =
-        ChipDefaults.chipColors(backgroundColor = colorResource(R.color.wear_material_almond)),
+        colors = ChipDefaults.primaryChipColors(),
     )
 }
 
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt
index e7a854f..22f6bf0 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt
@@ -26,7 +26,6 @@
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
-import com.android.compose.theme.LocalAndroidColorScheme
 import androidx.wear.compose.material.MaterialTheme as WearMaterialTheme
 
 @Composable
@@ -34,7 +33,7 @@
     Text(
         modifier = modifier.wrapContentSize(),
         text = text,
-        color = LocalAndroidColorScheme.current.onSurface,
+        color = WearMaterialTheme.colors.onSurface,
         textAlign = TextAlign.Center,
         style = WearMaterialTheme.typography.title3,
     )
@@ -45,7 +44,7 @@
     Text(
         modifier = modifier.wrapContentSize(),
         text = text,
-        color = LocalAndroidColorScheme.current.onSurface,
+        color = WearMaterialTheme.colors.onSurfaceVariant,
         textAlign = TextAlign.Center,
         overflow = TextOverflow.Ellipsis,
         maxLines = 2,
@@ -56,28 +55,30 @@
 @Composable
 fun WearUsernameText(
     text: String,
+    textAlign: TextAlign = TextAlign.Center,
     modifier: Modifier = Modifier,
     onTextLayout: (TextLayoutResult) -> Unit = {},
 ) {
     Text(
         modifier = modifier.padding(start = 8.dp, end = 8.dp).wrapContentSize(),
         text = text,
-        color = LocalAndroidColorScheme.current.onSurfaceVariant,
+        color = WearMaterialTheme.colors.onSurfaceVariant,
         style = WearMaterialTheme.typography.caption1,
         overflow = TextOverflow.Ellipsis,
-        textAlign = TextAlign.Center,
+        textAlign = textAlign,
         maxLines = 2,
         onTextLayout = onTextLayout,
     )
 }
 
+// used for primary label in button
 @Composable
 fun WearButtonText(
     text: String,
     textAlign: TextAlign,
     maxLines: Int = 1,
     modifier: Modifier = Modifier,
-    color: Color = LocalAndroidColorScheme.current.onSurface,
+    color: Color = WearMaterialTheme.colors.onSurface,
     onTextLayout: (TextLayoutResult) -> Unit = {},
 ) {
     Text(
@@ -101,8 +102,8 @@
     Text(
         modifier = modifier.wrapContentSize(),
         text = text,
-        color = LocalAndroidColorScheme.current.onSurfaceVariant,
-        style = WearMaterialTheme.typography.button,
+        color = WearMaterialTheme.colors.onSurfaceVariant,
+        style = WearMaterialTheme.typography.caption1,
         overflow = TextOverflow.Ellipsis,
         textAlign = TextAlign.Start,
         maxLines = 1,
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
index 7a936b6..0417533 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
@@ -16,6 +16,7 @@
 
 package com.android.credentialmanager.ui.mappers
 
+import android.graphics.drawable.Drawable
 import com.android.credentialmanager.model.Request
 import com.android.credentialmanager.CredentialSelectorUiState
 import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerUserNameEntries
@@ -35,10 +36,19 @@
                 entry = accounts[0].value.minWith(comparator)
             )
         } else {
-            CredentialSelectorUiState.Get.SingleEntryPerAccount(
-                sortedEntries = accounts.map {
-                    it.value.minWith(comparator)
-                }.sortedWith(comparator),
+            val sortedEntries = accounts.map {
+                it.value.minWith(comparator)
+            }.sortedWith(comparator)
+
+            var icon: Drawable? = null
+            // provide icon if all entries have the same provider
+            if (sortedEntries.all {it.providerId == sortedEntries[0].providerId}) {
+                icon = providerInfos[0].icon
+            }
+
+            CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen(
+                sortedEntries = sortedEntries,
+                icon = icon,
                 authenticationEntryList = providerInfos.flatMap { it.authenticationEntryList }
             )
         }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt
index acf4eca..23163d5 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt
@@ -48,7 +48,7 @@
 @OptIn(ExperimentalHorologistApi::class)
 @Composable
 fun MultiCredentialsFoldScreen(
-    credentialSelectorUiState: CredentialSelectorUiState.Get.SingleEntryPerAccount,
+    credentialSelectorUiState: CredentialSelectorUiState.Get.MultipleEntryPrimaryScreen,
     columnState: ScalingLazyColumnState,
     flowEngine: FlowEngine,
 ) {
@@ -68,7 +68,7 @@
             }
 
             SignInHeader(
-                icon = null,
+                icon = credentialSelectorUiState.icon,
                 title = title,
             )
         }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/theme/WearCredentialSelectorTheme.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/theme/WearCredentialSelectorTheme.kt
new file mode 100644
index 0000000..ee0ba7b
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/theme/WearCredentialSelectorTheme.kt
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2024 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.credentialmanager.ui.theme
+
+import android.content.Context
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.annotation.StringRes
+import androidx.wear.compose.material.Colors
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.font.DeviceFontFamilyName
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
+import androidx.wear.compose.material.Typography
+import androidx.wear.compose.material.MaterialTheme
+import com.android.credentialmanager.R
+import androidx.compose.ui.graphics.Color
+
+/** The Material 3 Theme Wrapper for Supporting RRO. */
+@Composable
+fun WearCredentialSelectorTheme(content: @Composable () -> Unit) {
+    val context = LocalContext.current
+    val colors =
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            overlayColors(context)
+                .copy(error = MaterialTheme.colors.error, onError = MaterialTheme.colors.onError)
+        } else {
+            MaterialTheme.colors
+        }
+    MaterialTheme(colors = colors, typography = deviceDefaultTypography(context), content = content)
+}
+
+/**
+ * Creates a dynamic color maps that can be overlaid. 100 - Lightest shade; 0 - Darkest Shade; In
+ * wear we only support dark theme for the time being. Thus the fill colors and variants are dark
+ * and anything on top is light. We will use this custom redirection until wear compose material
+ * supports color scheming.
+ *
+ * The mapping is best case match on wear material color tokens from
+ * /android/clockwork/common/wearable/wearmaterial/color/res/values/color-tokens.xml
+ *
+ * @param context The context required to get system resource data.
+ */
+@RequiresApi(Build.VERSION_CODES.S)
+internal fun overlayColors(context: Context): Colors {
+    val tonalPalette = dynamicTonalPalette(context)
+    return Colors(
+        background = Color.Black,
+        onBackground = Color.White,
+        primary = tonalPalette.primary90,
+        primaryVariant = tonalPalette.primary80,
+        onPrimary = tonalPalette.primary10,
+        secondary = tonalPalette.tertiary90,
+        secondaryVariant = tonalPalette.tertiary60,
+        onSecondary = tonalPalette.tertiary10,
+        surface = tonalPalette.neutral20,
+        onSurface = tonalPalette.neutral95,
+        onSurfaceVariant = tonalPalette.neutralVariant80,
+    )
+}
+
+private fun fontFamily(context: Context, @StringRes id: Int): FontFamily {
+    val typefaceName = context.resources.getString(id)
+    val font = Font(familyName = DeviceFontFamilyName(typefaceName))
+    return FontFamily(font)
+}
+
+/*
+ Only customizes font family. The material 3 roles to 2.5 are mapped to the best case matching of
+ google3/java/com/google/android/wearable/libraries/compose/theme/GoogleMaterialTheme.kt
+*/
+internal fun deviceDefaultTypography(context: Context): Typography {
+    val defaultTypography = Typography()
+    return Typography(
+        display1 =
+        defaultTypography.display1.copy(
+            fontFamily =
+            fontFamily(context, R.string.wear_material_compose_display_1_font_family)
+        ),
+        display2 =
+        defaultTypography.display2.copy(
+            fontFamily =
+            fontFamily(context, R.string.wear_material_compose_display_2_font_family)
+        ),
+        display3 =
+        defaultTypography.display1.copy(
+            fontFamily =
+            fontFamily(context, R.string.wear_material_compose_display_3_font_family)
+        ),
+        title1 =
+        defaultTypography.title1.copy(
+            fontFamily = fontFamily(context, R.string.wear_material_compose_title_1_font_family)
+        ),
+        title2 =
+        defaultTypography.title2.copy(
+            fontFamily = fontFamily(context, R.string.wear_material_compose_title_2_font_family)
+        ),
+        title3 =
+        defaultTypography.title3.copy(
+            fontFamily = fontFamily(context, R.string.wear_material_compose_title_3_font_family)
+        ),
+        body1 =
+        defaultTypography.body1.copy(
+            fontFamily = fontFamily(context, R.string.wear_material_compose_body_1_font_family)
+        ),
+        body2 =
+        defaultTypography.body2.copy(
+            fontFamily = fontFamily(context, R.string.wear_material_compose_body_2_font_family)
+        ),
+        button =
+        defaultTypography.button.copy(
+            fontFamily = fontFamily(context, R.string.wear_material_compose_button_font_family)
+        ),
+        caption1 =
+        defaultTypography.caption1.copy(
+            fontFamily =
+            fontFamily(context, R.string.wear_material_compose_caption_1_font_family)
+        ),
+        caption2 =
+        defaultTypography.caption2.copy(
+            fontFamily =
+            fontFamily(context, R.string.wear_material_compose_caption_2_font_family)
+        ),
+        caption3 =
+        defaultTypography.caption3.copy(
+            fontFamily =
+            fontFamily(context, R.string.wear_material_compose_caption_3_font_family)
+        ),
+    )
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/theme/WearCredentialTonalPalette.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/theme/WearCredentialTonalPalette.kt
new file mode 100644
index 0000000..1d6ed33
--- /dev/null
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/theme/WearCredentialTonalPalette.kt
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2024 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.credentialmanager.ui.theme
+
+import android.R
+import android.content.Context
+import android.os.Build
+import androidx.annotation.ColorRes
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+
+import androidx.compose.ui.graphics.Color
+
+/**
+ * Tonal Palette structure in Material.
+ *
+ * A tonal palette is comprised of 5 tonal ranges. Each tonal range includes the 13 stops, or tonal
+ * swatches.
+ *
+ * Tonal range names are:
+ * - Neutral (N)
+ * - Neutral variant (NV)
+ * - Primary (P)
+ * - Secondary (S)
+ * - Tertiary (T)
+ */
+internal class WearCredentialSelectorTonalPalette(
+    // The neutral tonal range.
+    val neutral100: Color,
+    val neutral99: Color,
+    val neutral95: Color,
+    val neutral90: Color,
+    val neutral80: Color,
+    val neutral70: Color,
+    val neutral60: Color,
+    val neutral50: Color,
+    val neutral40: Color,
+    val neutral30: Color,
+    val neutral20: Color,
+    val neutral10: Color,
+    val neutral0: Color,
+
+    // The neutral variant tonal range, sometimes called "neutral 2"
+    val neutralVariant100: Color,
+    val neutralVariant99: Color,
+    val neutralVariant95: Color,
+    val neutralVariant90: Color,
+    val neutralVariant80: Color,
+    val neutralVariant70: Color,
+    val neutralVariant60: Color,
+    val neutralVariant50: Color,
+    val neutralVariant40: Color,
+    val neutralVariant30: Color,
+    val neutralVariant20: Color,
+    val neutralVariant10: Color,
+    val neutralVariant0: Color,
+
+    // The primary tonal range, also known as accent 1
+    val primary100: Color,
+    val primary99: Color,
+    val primary95: Color,
+    val primary90: Color,
+    val primary80: Color,
+    val primary70: Color,
+    val primary60: Color,
+    val primary50: Color,
+    val primary40: Color,
+    val primary30: Color,
+    val primary20: Color,
+    val primary10: Color,
+    val primary0: Color,
+
+    // The Secondary tonal range, also know as accent 2
+    val secondary100: Color,
+    val secondary99: Color,
+    val secondary95: Color,
+    val secondary90: Color,
+    val secondary80: Color,
+    val secondary70: Color,
+    val secondary60: Color,
+    val secondary50: Color,
+    val secondary40: Color,
+    val secondary30: Color,
+    val secondary20: Color,
+    val secondary10: Color,
+    val secondary0: Color,
+
+    // The tertiary tonal range, also known as accent 3
+    val tertiary100: Color,
+    val tertiary99: Color,
+    val tertiary95: Color,
+    val tertiary90: Color,
+    val tertiary80: Color,
+    val tertiary70: Color,
+    val tertiary60: Color,
+    val tertiary50: Color,
+    val tertiary40: Color,
+    val tertiary30: Color,
+    val tertiary20: Color,
+    val tertiary10: Color,
+    val tertiary0: Color,
+)
+/** Dynamic colors for wear compose material to support resource overlay. */
+@RequiresApi(Build.VERSION_CODES.S)
+// TODO: once we have proper support for this on Wear 6+, we will do something similar to
+// https://source.corp.google.com/h/android/platform/superproject/+/androidx-main:frameworks/support/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DynamicTonalPalette.android.kt;l=307-362?q=dynamicTonalPalette&sq=repo:android%2Fplatform%2Fsuperproject%20b:androidx-main
+// Tracking Bug: b/270720571
+internal fun dynamicTonalPalette(context: Context) =
+    WearCredentialSelectorTonalPalette(
+        // The neutral tonal range from the generated dynamic color palette.
+        neutral100 = ColorResourceHelper.getColor(context, R.color.system_neutral1_0),
+        neutral99 = ColorResourceHelper.getColor(context, R.color.system_neutral1_10),
+        neutral95 = ColorResourceHelper.getColor(context, R.color.system_neutral1_50),
+        neutral90 = ColorResourceHelper.getColor(context, R.color.system_neutral1_100),
+        neutral80 = ColorResourceHelper.getColor(context, R.color.system_neutral1_200),
+        neutral70 = ColorResourceHelper.getColor(context, R.color.system_neutral1_300),
+        neutral60 = ColorResourceHelper.getColor(context, R.color.system_neutral1_400),
+        neutral50 = ColorResourceHelper.getColor(context, R.color.system_neutral1_500),
+        neutral40 = ColorResourceHelper.getColor(context, R.color.system_neutral1_600),
+        neutral30 = ColorResourceHelper.getColor(context, R.color.system_neutral1_700),
+        neutral20 = ColorResourceHelper.getColor(context, R.color.system_neutral1_800),
+        neutral10 = ColorResourceHelper.getColor(context, R.color.system_neutral1_900),
+        neutral0 = ColorResourceHelper.getColor(context, R.color.system_neutral1_1000),
+
+        // The neutral variant tonal range, sometimes called "neutral 2",  from the
+        // generated dynamic color palette.
+        neutralVariant100 = ColorResourceHelper.getColor(context, R.color.system_neutral2_0),
+        neutralVariant99 = ColorResourceHelper.getColor(context, R.color.system_neutral2_10),
+        neutralVariant95 = ColorResourceHelper.getColor(context, R.color.system_neutral2_50),
+        neutralVariant90 = ColorResourceHelper.getColor(context, R.color.system_neutral2_100),
+        neutralVariant80 = ColorResourceHelper.getColor(context, R.color.system_neutral2_200),
+        neutralVariant70 = ColorResourceHelper.getColor(context, R.color.system_neutral2_300),
+        neutralVariant60 = ColorResourceHelper.getColor(context, R.color.system_neutral2_400),
+        neutralVariant50 = ColorResourceHelper.getColor(context, R.color.system_neutral2_500),
+        neutralVariant40 = ColorResourceHelper.getColor(context, R.color.system_neutral2_600),
+        neutralVariant30 = ColorResourceHelper.getColor(context, R.color.system_neutral2_700),
+        neutralVariant20 = ColorResourceHelper.getColor(context, R.color.system_neutral2_800),
+        neutralVariant10 = ColorResourceHelper.getColor(context, R.color.system_neutral2_900),
+        neutralVariant0 = ColorResourceHelper.getColor(context, R.color.system_neutral2_1000),
+
+        // The primary tonal range from the generated dynamic color palette.
+        primary100 = ColorResourceHelper.getColor(context, R.color.system_accent1_0),
+        primary99 = ColorResourceHelper.getColor(context, R.color.system_accent1_10),
+        primary95 = ColorResourceHelper.getColor(context, R.color.system_accent1_50),
+        primary90 = ColorResourceHelper.getColor(context, R.color.system_accent1_100),
+        primary80 = ColorResourceHelper.getColor(context, R.color.system_accent1_200),
+        primary70 = ColorResourceHelper.getColor(context, R.color.system_accent1_300),
+        primary60 = ColorResourceHelper.getColor(context, R.color.system_accent1_400),
+        primary50 = ColorResourceHelper.getColor(context, R.color.system_accent1_500),
+        primary40 = ColorResourceHelper.getColor(context, R.color.system_accent1_600),
+        primary30 = ColorResourceHelper.getColor(context, R.color.system_accent1_700),
+        primary20 = ColorResourceHelper.getColor(context, R.color.system_accent1_800),
+        primary10 = ColorResourceHelper.getColor(context, R.color.system_accent1_900),
+        primary0 = ColorResourceHelper.getColor(context, R.color.system_accent1_1000),
+
+        // The secondary tonal range from the generated dynamic color palette.
+        secondary100 = ColorResourceHelper.getColor(context, R.color.system_accent2_0),
+        secondary99 = ColorResourceHelper.getColor(context, R.color.system_accent2_10),
+        secondary95 = ColorResourceHelper.getColor(context, R.color.system_accent2_50),
+        secondary90 = ColorResourceHelper.getColor(context, R.color.system_accent2_100),
+        secondary80 = ColorResourceHelper.getColor(context, R.color.system_accent2_200),
+        secondary70 = ColorResourceHelper.getColor(context, R.color.system_accent2_300),
+        secondary60 = ColorResourceHelper.getColor(context, R.color.system_accent2_400),
+        secondary50 = ColorResourceHelper.getColor(context, R.color.system_accent2_500),
+        secondary40 = ColorResourceHelper.getColor(context, R.color.system_accent2_600),
+        secondary30 = ColorResourceHelper.getColor(context, R.color.system_accent2_700),
+        secondary20 = ColorResourceHelper.getColor(context, R.color.system_accent2_800),
+        secondary10 = ColorResourceHelper.getColor(context, R.color.system_accent2_900),
+        secondary0 = ColorResourceHelper.getColor(context, R.color.system_accent2_1000),
+
+        // The tertiary tonal range from the generated dynamic color palette.
+        tertiary100 = ColorResourceHelper.getColor(context, R.color.system_accent3_0),
+        tertiary99 = ColorResourceHelper.getColor(context, R.color.system_accent3_10),
+        tertiary95 = ColorResourceHelper.getColor(context, R.color.system_accent3_50),
+        tertiary90 = ColorResourceHelper.getColor(context, R.color.system_accent3_100),
+        tertiary80 = ColorResourceHelper.getColor(context, R.color.system_accent3_200),
+        tertiary70 = ColorResourceHelper.getColor(context, R.color.system_accent3_300),
+        tertiary60 = ColorResourceHelper.getColor(context, R.color.system_accent3_400),
+        tertiary50 = ColorResourceHelper.getColor(context, R.color.system_accent3_500),
+        tertiary40 = ColorResourceHelper.getColor(context, R.color.system_accent3_600),
+        tertiary30 = ColorResourceHelper.getColor(context, R.color.system_accent3_700),
+        tertiary20 = ColorResourceHelper.getColor(context, R.color.system_accent3_800),
+        tertiary10 = ColorResourceHelper.getColor(context, R.color.system_accent3_900),
+        tertiary0 = ColorResourceHelper.getColor(context, R.color.system_accent3_1000),
+    )
+
+private object ColorResourceHelper {
+    @DoNotInline
+    fun getColor(context: Context, @ColorRes id: Int): Color {
+        return Color(context.resources.getColor(id, context.theme))
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index 8137e40..14ebc39 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -32,6 +32,16 @@
 }
 
 flag {
+    name: "floating_menu_narrow_target_content_observer"
+    namespace: "accessibility"
+    description: "stops the FAB from monitoring enabled services to trigger target content changes."
+    bug: "331740049"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "floating_menu_overlaps_nav_bars_flag"
     namespace: "accessibility"
     description: "Adjusts bounds to allow the floating menu to render on top of navigation bars."
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index b105a4e..ef5e292 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -477,10 +477,13 @@
 }
 
 flag {
-    name: "screenshot_private_profile"
+    name: "screenshot_private_profile_behavior_fix"
     namespace: "systemui"
     description: "Private profile support for screenshots"
     bug: "327613051"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
 }
 
 flag {
diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/FingerprintSensor.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/FingerprintSensor.kt
index a2b1198..f07dce5 100644
--- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/FingerprintSensor.kt
+++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/FingerprintSensor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.biometrics.shared.model
 
+import android.graphics.Rect
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 
 /** Fingerprint sensor property. Represents [FingerprintSensorPropertiesInternal]. */
@@ -23,12 +24,23 @@
     val sensorId: Int,
     val sensorStrength: SensorStrength,
     val maxEnrollmentsPerUser: Int,
-    val sensorType: FingerprintSensorType
+    val sensorType: FingerprintSensorType,
+    val sensorBounds: Rect,
+    val sensorRadius: Int,
 )
 
 /** Convert [FingerprintSensorPropertiesInternal] to corresponding [FingerprintSensor] */
 fun FingerprintSensorPropertiesInternal.toFingerprintSensor(): FingerprintSensor {
     val sensorStrength: SensorStrength = this.sensorStrength.toSensorStrength()
     val sensorType: FingerprintSensorType = this.sensorType.toSensorType()
-    return FingerprintSensor(this.sensorId, sensorStrength, this.maxEnrollmentsPerUser, sensorType)
+    val sensorBounds: Rect = this.location.rect
+    val sensorRadius = this.location.sensorRadius
+    return FingerprintSensor(
+        this.sensorId,
+        sensorStrength,
+        this.maxEnrollmentsPerUser,
+        sensorType,
+        sensorBounds,
+        sensorRadius,
+    )
 }
diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt
index 476daac..0f3d285 100644
--- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt
+++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt
@@ -33,3 +33,10 @@
         SensorProperties.STRENGTH_STRONG -> SensorStrength.STRONG
         else -> throw IllegalArgumentException("Invalid SensorStrength value: $this")
     }
+/** Convert [SensorStrength] to corresponding [Int] */
+fun SensorStrength.toInt(): Int =
+    when (this) {
+        SensorStrength.CONVENIENCE -> SensorProperties.STRENGTH_CONVENIENCE
+        SensorStrength.WEAK -> SensorProperties.STRENGTH_WEAK
+        SensorStrength.STRONG -> SensorProperties.STRENGTH_STRONG
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
index 1018f70..eb840f1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
@@ -244,11 +244,13 @@
                 mSecureSettings.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS),
                 /* notifyForDescendants */ false, mMenuTargetFeaturesContentObserver,
                 UserHandle.USER_CURRENT);
-        mSecureSettings.registerContentObserverForUser(
-                mSecureSettings.getUriFor(ENABLED_ACCESSIBILITY_SERVICES),
-                /* notifyForDescendants */ false,
-                mMenuTargetFeaturesContentObserver,
-                UserHandle.USER_CURRENT);
+        if (!com.android.systemui.Flags.floatingMenuNarrowTargetContentObserver()) {
+            mSecureSettings.registerContentObserverForUser(
+                    mSecureSettings.getUriFor(ENABLED_ACCESSIBILITY_SERVICES),
+                    /* notifyForDescendants */ false,
+                    mMenuTargetFeaturesContentObserver,
+                    UserHandle.USER_CURRENT);
+        }
         mSecureSettings.registerContentObserverForUser(
                 mSecureSettings.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE),
                 /* notifyForDescendants */ false, mMenuSizeContentObserver,
@@ -263,8 +265,10 @@
                 UserHandle.USER_CURRENT);
         mContext.registerComponentCallbacks(mComponentCallbacks);
 
-        mAccessibilityManager.addAccessibilityServicesStateChangeListener(
-                mA11yServicesStateChangeListener);
+        if (!com.android.systemui.Flags.floatingMenuNarrowTargetContentObserver()) {
+            mAccessibilityManager.addAccessibilityServicesStateChangeListener(
+                    mA11yServicesStateChangeListener);
+        }
     }
 
     void unregisterObserversAndCallbacks() {
@@ -273,8 +277,10 @@
         mContext.getContentResolver().unregisterContentObserver(mMenuFadeOutContentObserver);
         mContext.unregisterComponentCallbacks(mComponentCallbacks);
 
-        mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
-                mA11yServicesStateChangeListener);
+        if (!com.android.systemui.Flags.floatingMenuNarrowTargetContentObserver()) {
+            mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
+                    mA11yServicesStateChangeListener);
+        }
     }
 
     interface OnSettingsContentsChanged {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt b/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt
index a6b01e7..44f767a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt
@@ -19,7 +19,7 @@
 import android.content.ComponentName
 import android.content.Context
 import android.os.Process
-import com.android.systemui.Flags.screenshotPrivateProfile
+import com.android.systemui.Flags.screenshotPrivateProfileBehaviorFix
 import com.android.systemui.SystemUIService
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -72,7 +72,7 @@
             displayContentRepoProvider: Provider<DisplayContentRepository>,
             policyListProvider: Provider<List<CapturePolicy>>,
         ): ScreenshotRequestProcessor {
-            return if (screenshotPrivateProfile()) {
+            return if (screenshotPrivateProfileBehaviorFix()) {
                 PolicyRequestProcessor(
                     background = background,
                     capture = imageCapture,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionExecutorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionExecutorTest.kt
index 5e7d8fb..91f3912 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionExecutorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionExecutorTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
+import kotlin.test.Ignore
 import kotlin.test.Test
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -55,6 +56,7 @@
 
     private lateinit var actionExecutor: ActionExecutor
 
+    @Ignore // Fixed with newer mockito version (in main)
     @Test
     fun startSharedTransition_callsLaunchIntent() = runTest {
         actionExecutor = createActionExecutor()
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index bfa1c7b..8ab2e0f 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -56,6 +56,13 @@
 }
 
 flag {
+  name: "enable_hardware_shortcut_disables_warning"
+  namespace: "accessibility"
+  description: "When the user purposely enables the hardware shortcut, preemptively disables the first-time warning message."
+  bug: "287065325"
+}
+
+flag {
     name: "enable_magnification_joystick"
     namespace: "accessibility"
     description: "Whether to enable joystick controls for magnification"
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e64e500..ccf9a90 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4273,6 +4273,13 @@
         }
         if (shortcutType == UserShortcutType.HARDWARE) {
             skipVolumeShortcutDialogTimeoutRestriction(userId);
+            if (com.android.server.accessibility.Flags.enableHardwareShortcutDisablesWarning()) {
+                persistIntToSetting(
+                        userId,
+                        Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+                        AccessibilityShortcutController.DialogStatus.SHOWN
+                );
+            }
         } else if (shortcutType == UserShortcutType.SOFTWARE) {
             // Update the A11y FAB size to large when the Magnification shortcut is
             // enabled and the user hasn't changed the floating button size
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 1741593..ccc44a4 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import static com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis;
+
 import android.app.ActivityManager;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
@@ -70,12 +72,6 @@
      */
     @VisibleForTesting static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
 
-    /**
-     * Min time in milliseconds to complete the emergency gesture for it count. If the gesture is
-     * completed faster than this, we assume it's not performed by human and the
-     * event gets ignored.
-     */
-    @VisibleForTesting static final int EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS = 200;
 
     /**
      * Interval in milliseconds in which the power button must be depressed in succession to be
@@ -570,7 +566,8 @@
                     long emergencyGestureTapDetectionMinTimeMs = Settings.Global.getInt(
                             mContext.getContentResolver(),
                             Settings.Global.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS,
-                            EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS);
+                            mContext.getResources().getInteger(
+                                    config_defaultMinEmergencyGestureTapDurationMillis));
                     if (emergencyGestureSpentTime <= emergencyGestureTapDetectionMinTimeMs) {
                         Slog.i(TAG, "Emergency gesture detected but it's too fast. Gesture time: "
                                 + emergencyGestureSpentTime + " ms");
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index f7f76aa..57ea233 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -807,7 +807,7 @@
                     getDefaultSystemHandlerActivityPackage(pm,
                             SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
                     userId, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
-                    NOTIFICATION_PERMISSIONS, PHONE_PERMISSIONS);
+                    NOTIFICATION_PERMISSIONS, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS);
         }
 
         // Voice recognition
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 4e059b4..fe883e4 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -17,7 +17,6 @@
 package com.android.server;
 
 import static com.android.server.GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
-import static com.android.server.GestureLauncherService.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -1449,7 +1448,7 @@
         long emergencyGestureTapDetectionMinTimeMs = Settings.Global.getInt(
                 mContext.getContentResolver(),
                 Settings.Global.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS,
-                EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS);
+                200);
         assertTrue(intercepted);
         if (tapIntervalMs * 4 > emergencyGestureTapDetectionMinTimeMs) {
             assertTrue(outLaunched.value);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 1bf9a9d..5a17851 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -69,10 +69,9 @@
 import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
@@ -144,8 +143,7 @@
             ApplicationProvider.getApplicationContext());
 
     @Rule
-    public final CheckFlagsRule mCheckFlagsRule =
-            DeviceFlagsValueProvider.createCheckFlagsRule();
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private static final int ACTION_ID = 20;
     private static final String LABEL = "label";
@@ -624,7 +622,7 @@
 
     @SmallTest
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
+    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void testOnClientChange_magnificationTwoFingerTripleTapEnabled_requestConnection() {
         when(mProxyManager.canRetrieveInteractiveWindowsLocked()).thenReturn(false);
 
@@ -642,7 +640,7 @@
 
     @SmallTest
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
+    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void testOnClientChange_magnificationTwoFingerTripleTapDisabled_requestDisconnection() {
         when(mProxyManager.canRetrieveInteractiveWindowsLocked()).thenReturn(false);
 
@@ -704,7 +702,7 @@
 
     @SmallTest
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
+    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void onClientChange_magnificationTwoFingerTripleTapDisabled_removeMagnificationButton() {
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
@@ -720,7 +718,7 @@
 
     @SmallTest
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
+    @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void onClientChange_magnificationTwoFingerTripleTapEnabled_keepMagnificationButton() {
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
@@ -772,7 +770,7 @@
 
     @SmallTest
     @Test
-    @RequiresFlagsDisabled(com.android.systemui.Flags.FLAG_HEARING_AIDS_QS_TILE_DIALOG)
+    @DisableFlags(com.android.systemui.Flags.FLAG_HEARING_AIDS_QS_TILE_DIALOG)
     public void testPerformAccessibilityShortcut_hearingAids_startActivityWithExpectedComponent() {
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
@@ -790,7 +788,7 @@
 
     @SmallTest
     @Test
-    @RequiresFlagsEnabled(com.android.systemui.Flags.FLAG_HEARING_AIDS_QS_TILE_DIALOG)
+    @EnableFlags(com.android.systemui.Flags.FLAG_HEARING_AIDS_QS_TILE_DIALOG)
     public void testPerformAccessibilityShortcut_hearingAids_sendExpectedBroadcast() {
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
@@ -949,7 +947,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_SKIP_ACCESSIBILITY_WARNING_DIALOG_FOR_TRUSTED_SERVICES)
+    @EnableFlags(FLAG_SKIP_ACCESSIBILITY_WARNING_DIALOG_FOR_TRUSTED_SERVICES)
     public void testIsAccessibilityServiceWarningRequired_notRequiredIfAllowlisted() {
         mockManageAccessibilityGranted(mTestableContext);
         final AccessibilityServiceInfo info_a = mockAccessibilityServiceInfo(
@@ -1008,6 +1006,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_HARDWARE_SHORTCUT_DISABLES_WARNING)
+    public void enableHardwareShortcutsForTargets_shortcutDialogSetting_isShown() {
+        Settings.Secure.putInt(
+                mTestableContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+                AccessibilityShortcutController.DialogStatus.NOT_SHOWN
+        );
+
+        mockManageAccessibilityGranted(mTestableContext);
+        setupShortcutTargetServices();
+        String target = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
+
+        mA11yms.enableShortcutsForTargets(
+                /* enable= */ true,
+                UserShortcutType.HARDWARE,
+                List.of(target),
+                mA11yms.getCurrentUserIdLocked());
+        mTestableLooper.processAllMessages();
+
+        assertThat(Settings.Secure.getInt(
+                mTestableContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+                AccessibilityShortcutController.DialogStatus.NOT_SHOWN))
+                .isEqualTo(AccessibilityShortcutController.DialogStatus.SHOWN);
+    }
+
+    @Test
     public void enableShortcutsForTargets_disableSoftwareShortcut_shortcutTurnedOff()
             throws Exception {
         String target = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
@@ -1341,7 +1366,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_statusBarServiceNotGranted_throwsException() {
         mTestableContext.getTestablePermissions().setPermission(
                 Manifest.permission.STATUS_BAR_SERVICE, PackageManager.PERMISSION_DENIED);
@@ -1355,7 +1380,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_manageAccessibilityNotGranted_throwsException() {
         mockStatusBarServiceGranted(mTestableContext);
         mTestableContext.getTestablePermissions().setPermission(
@@ -1369,7 +1394,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_qsTileChanges_updateA11yTilesInQsPanel() {
         mockStatusBarServiceGranted(mTestableContext);
         mockManageAccessibilityGranted(mTestableContext);
@@ -1389,7 +1414,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_sameQsTiles_noUpdateToA11yTilesInQsPanel() {
         notifyQuickSettingsTilesChanged_qsTileChanges_updateA11yTilesInQsPanel();
         List<ComponentName> tiles =
@@ -1406,7 +1431,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_serviceWarningRequired_qsShortcutRemainDisabled() {
         mockStatusBarServiceGranted(mTestableContext);
         mockManageAccessibilityGranted(mTestableContext);
@@ -1424,7 +1449,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_serviceWarningNotRequired_qsShortcutEnabled() {
         mockStatusBarServiceGranted(mTestableContext);
         mockManageAccessibilityGranted(mTestableContext);
@@ -1446,7 +1471,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_addFrameworkTile_qsShortcutEnabled() {
         mockStatusBarServiceGranted(mTestableContext);
         mockManageAccessibilityGranted(mTestableContext);
@@ -1469,7 +1494,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void notifyQuickSettingsTilesChanged_removeFrameworkTile_qsShortcutDisabled() {
         notifyQuickSettingsTilesChanged_addFrameworkTile_qsShortcutEnabled();
         Set<ComponentName> qsTiles = mA11yms.getCurrentUserState().getA11yQsTilesInQsPanel();
@@ -1487,7 +1512,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void restoreAccessibilityQsTargets_a11yQsTargetsRestored() {
         String daltonizerTile =
                 AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString();
@@ -1510,7 +1535,7 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
+    @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
     public void restoreAccessibilityQsTargets_a11yQsTargetsNotRestored() {
         String daltonizerTile =
                 AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString();